1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-12-23 01:16:18 +00:00

First steps of a watcher test suite

This commit is contained in:
spl0k 2017-12-05 23:18:39 +01:00
parent bb72ce8f7c
commit f63a9ed4cc
3 changed files with 155 additions and 7 deletions

View File

@ -12,12 +12,14 @@ import unittest
from .test_db import DbTestCase from .test_db import DbTestCase
from .test_scanner import ScannerTestCase from .test_scanner import ScannerTestCase
from .test_watcher import suite as watcher_suite
def suite(): def suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(DbTestCase)) suite.addTest(unittest.makeSuite(DbTestCase))
suite.addTest(unittest.makeSuite(ScannerTestCase)) suite.addTest(unittest.makeSuite(ScannerTestCase))
suite.addTest(watcher_suite())
return suite return suite

144
tests/base/test_watcher.py Normal file
View File

@ -0,0 +1,144 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
#
# This file is part of Supysonic.
# Supysonic is a Python implementation of the Subsonic server API.
#
# Copyright (C) 2017 Alban 'spl0k' Féron
#
# Distributed under terms of the GNU AGPLv3 license.
import io
import os
import shutil
import tempfile
import time
import unittest
from contextlib import contextmanager
from threading import Thread
from supysonic.db import get_store, Track, Artist
from supysonic.managers.folder import FolderManager
from supysonic.watcher import SupysonicWatcher
from ..testbase import TestConfig
class WatcherTestConfig(TestConfig):
DAEMON = {
'wait_delay': 0.5,
'log_file': None,
'log_level': 'DEBUG'
}
def __init__(self, db_uri):
super(WatcherTestConfig, self).__init__(False, False)
self.BASE['database_uri'] = db_uri
class WatcherTestBase(unittest.TestCase):
@contextmanager
def _get_store(self):
store = None
try:
store = get_store('sqlite:///' + self.__dbfile)
yield store
store.commit()
store.close()
except:
store.rollback()
store.close()
raise
def setUp(self):
self.__dbfile = tempfile.mkstemp()[1]
conf = WatcherTestConfig('sqlite:///' + self.__dbfile)
self.__sleep_time = conf.DAEMON['wait_delay'] + 1
with self._get_store() as store:
with io.open('schema/sqlite.sql', 'r') as sql:
schema = sql.read()
for statement in schema.split(';'):
store.execute(statement)
self.__watcher = SupysonicWatcher(conf)
self.__thread = Thread(target = self.__watcher.run)
def tearDown(self):
os.unlink(self.__dbfile)
def _start(self):
self.__thread.start()
time.sleep(0.2)
def _stop(self):
self.__watcher.stop()
self.__thread.join()
def _is_alive(self):
return self.__thread.is_alive()
def _sleep(self):
time.sleep(self.__sleep_time)
class NothingToWatchTestCase(WatcherTestBase):
def test_spawn_useless_watcher(self):
self._start()
time.sleep(0.2)
self.assertFalse(self._is_alive())
self._stop()
class WatcherTestCase(WatcherTestBase):
def setUp(self):
super(WatcherTestCase, self).setUp()
self.__dir = tempfile.mkdtemp()
with self._get_store() as store:
FolderManager.add(store, 'Folder', self.__dir)
self._start()
def tearDown(self):
self._stop()
shutil.rmtree(self.__dir)
super(WatcherTestCase, self).tearDown()
@staticmethod
def _tempname():
with tempfile.NamedTemporaryFile() as f:
return os.path.basename(f.name)
def assertTrackCountEqual(self, expected):
with self._get_store() as store:
self.assertEqual(store.find(Track).count(), expected)
def test_add(self):
shutil.copyfile('tests/assets/folder/silence.mp3', os.path.join(self.__dir, self._tempname() + '.mp3'))
self.assertTrackCountEqual(0)
self._sleep()
self.assertTrackCountEqual(1)
def test_add_nowait_stop(self):
shutil.copyfile('tests/assets/folder/silence.mp3', os.path.join(self.__dir, self._tempname() + '.mp3'))
self._stop()
self.assertTrackCountEqual(1)
def test_add_multiple(self):
shutil.copyfile('tests/assets/folder/silence.mp3', os.path.join(self.__dir, self._tempname() + '.mp3'))
shutil.copyfile('tests/assets/folder/silence.mp3', os.path.join(self.__dir, self._tempname() + '.mp3'))
shutil.copyfile('tests/assets/folder/silence.mp3', os.path.join(self.__dir, self._tempname() + '.mp3'))
self.assertTrackCountEqual(0)
self._sleep()
with self._get_store() as store:
self.assertEqual(store.find(Track).count(), 3)
self.assertEqual(store.find(Artist).count(), 1)
def suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(NothingToWatchTestCase))
suite.addTest(unittest.makeSuite(WatcherTestCase))
return suite
if __name__ == '__main__':
unittest.main()

View File

@ -8,6 +8,7 @@
# #
# Distributed under terms of the GNU AGPLv3 license. # Distributed under terms of the GNU AGPLv3 license.
import inspect
import io import io
import shutil import shutil
import sys import sys
@ -33,7 +34,8 @@ class TestConfig(DefaultConfig):
def __init__(self, with_webui, with_api): def __init__(self, with_webui, with_api):
super(TestConfig, self).__init__() super(TestConfig, self).__init__()
for attr, value in self.__class__.__dict__.iteritems(): for cls in reversed(inspect.getmro(self.__class__)):
for attr, value in cls.__dict__.iteritems():
if attr.startswith('_') or attr != attr.upper(): if attr.startswith('_') or attr != attr.upper():
continue continue