def test_copy_config_copies_config_files_to_app(self): """ tests that config files are copied to app and action is logged """ os.makedirs(os.path.join(self.app_home, self.app_name, self.app_name)) os.makedirs(os.path.join(os.path.dirname(self.app_home), 'conf.d')) conf = [ {'file': 'settings.json', 'move_to': os.path.join(self.app_home, self.app_name)}, {'file': '%s_uwsgi.ini' % self.app_name, 'move_to': self.app_home} ] for f in conf: with open(os.path.join(os.path.dirname(self.app_home), 'conf.d', f['file']), 'w') as config: config.write('%s file\n' % f['file']) install_django_app = InstallDjangoApp( self.dist_version, self.log_file, self.log_level, venv=self.venv, git_repo=self.git_repo ) install_django_app.copy_config(self.app_home) for f in conf: self.assertTrue(os.path.isfile(os.path.join(f['move_to'], f['file'])), f['file']) with open(os.path.join(f['move_to'], f['file'])) as file: file_list = [l for l in file] self.assertEqual(['%s file\n' % f['file']], file_list, file_list) self.log('INFO: app configuration file %s was copied to app' % f['file'])
def test_run_tests_exits_on_failed_test(self): """ tests that run_tests exits when app tests fail and writes to log. """ now = datetime.datetime.utcnow() yesterday = now - datetime.timedelta(days=1) os.makedirs(os.path.join(os.path.dirname(self.log_file), 'test_results'), exist_ok=True) os.makedirs(os.path.join(self.app_home, self.app_name), exist_ok=True) log_file_now = os.path.join( os.path.dirname(self.log_file), 'test_results', 'test_%s.log' % (now.strftime('%Y%m%d-%H%M%S')) ) log_file_yesterday = os.path.join( os.path.dirname(self.log_file), 'test_results', 'test_%s.log' % (yesterday.strftime('%Y%m%d-%H%M%S')) ) install_django_app = InstallDjangoApp( self.dist_version, self.log_file, self.log_level, venv=self.venv, git_repo=self.git_repo ) with open(log_file_now, 'w') as log: log.write('FAILED') with open(log_file_yesterday, 'w') as log: log.write('OK') try: install_django_app.run_tests(self.app_home) self.fail('run_tests did not exit on failed test') except SystemExit as error: self.assertEqual(1, error.code, 'run_tests exited with: %s' % str(error)) self.log('ERROR: %s tests failed' % self.app_name)
def test_stop_celery(self): """ tests that stop_celery runs the correct command and writes to log """ install_django_app = InstallDjangoApp( self.dist_version, self.log_file, self.log_level, venv=self.venv, git_repo=self.git_repo, celery_pid=self.celery_pid_path ) cmd = [ os.path.join(self.venv, 'bin', 'python'), '-m', 'celery', 'multi', 'stopwait', 'w1', '--pidfile=%s' % os.path.join(self.celery_pid_path, 'w1.pid'), ] cwd = os.path.join(self.app_home, self.app_name) msg = 'stopped celery and beat' func = 'stop_celery' args = (self.app_home,) # when celery is running os.makedirs(self.celery_pid_path, exist_ok=True) with open(os.path.join(self.celery_pid_path, 'w1.pid'), 'w') as pid: pid.write('celery pid') self.run_success([cmd], [msg], func, install_django_app.stop_celery, args) self.run_cwd(cwd, func, install_django_app.stop_celery, args) # when celery is not running if os.path.exists(os.path.join(self.celery_pid_path, 'w1.pid')): os.remove(os.path.join(self.celery_pid_path, 'w1.pid')) install_django_app.stop_celery(*args) self.log('INFO: did not stop celery, was not running')
def test_clone_app_does_nothing_if_app_is_alreday_installed(self): """ tests clone_app does nothing if app is already present and writes to log """ install_django_app = InstallDjangoApp( self.dist_version, self.log_file, self.log_level, venv=self.venv, git_repo='https://github.com/bla/tmp.git' ) install_django_app.clone_app('/') msg = 'INFO: app tmp already exists at /' self.log(msg)
def __init__(self, dist_version, app_home, log_file, log_level, git_repo='https://github.com/globz-eu/django_base.git', nginx_conf='/etc/nginx', sys_deps_file='system_dependencies.txt', reqs_file='requirements.txt', venv=''): InstallDjangoApp.__init__(self, dist_version, log_file, log_level, git_repo=git_repo, venv=venv) self.app_home = app_home self.nginx_conf = nginx_conf if self.dist_version == '14.04': self.nginx_cmd = ['service', 'nginx', 'restart'] elif self.dist_version == '16.04': self.nginx_cmd = ['systemctl', 'restart', 'nginx'] self.sys_deps_file = os.path.join(self.app_home, self.app_name, sys_deps_file) self.reqs_file = os.path.join(self.app_home, self.app_name, reqs_file)
def test_create_venv_does_nothing_if_already_present(self): """ tests create_venv does nothing if venv is already present and writes to log """ if self.dist_version == '14.04': self.python_version = 'python3.4' elif self.dist_version == '16.04': self.python_version = 'python3.5' os.makedirs(os.path.join(self.venv, 'lib', self.python_version)) install_django_app = InstallDjangoApp(self.dist_version, self.log_file, self.log_level, venv=self.venv) install_django_app.create_venv() msg = 'INFO: virtualenv %s already exists' % self.venv self.log(msg)
def test_deps_are_correctly_read(self): """ tests read_sys_deps returns correct structure """ deps_list = [ 'libpq-dev', 'python3-numpy', 'libxml2-dev', 'libxslt1-dev', 'zlib1g-dev', ] install_django_app = InstallDjangoApp(self.dist_version, self.log_file, self.log_level, venv=self.venv) deps = install_django_app.read_sys_deps(self.sys_deps_file) self.assertEqual(deps_list, deps, deps)
def test_stop_uwsgi_does_nothing_when_uwsgi_is_not_running(self, check_process_mock): """ tests that stop_uwsgi does nothing when uwsgi is not running """ mocks.alt_bool = Alternate([False]) install_django_app = InstallDjangoApp( self.dist_version, self.log_file, self.log_level, venv=self.venv, git_repo=self.git_repo, ) install_django_app.stop_uwsgi() self.log('INFO: did not stop uwsgi, was not running') self.assertEqual( [call('uwsgi')], check_process_mock.mock_calls, check_process_mock.mock_calls )
def copy_config_exits_when_conf_file_missing(self, conf): """ helper function that tests that copy_config exits when the conf file is missing :param conf: missing conf file """ install_django_app = InstallDjangoApp( self.dist_version, self.log_file, self.log_level, venv=self.venv, git_repo=self.git_repo ) try: install_django_app.copy_config(self.app_home) except SystemExit as error: self.assertEqual(1, error.code, 'copy_config' + ' exited with: ' + str(error)) self.log('ERROR: could not copy %s' % conf)
def test_run_tests_log_file(self): """ tests that run_tests logs to the right file. """ os.makedirs(os.path.join(self.app_home, self.app_name), exist_ok=True) install_django_app = InstallDjangoApp( self.dist_version, self.log_file, self.log_level, venv=self.venv, git_repo=self.git_repo, ) install_django_app.run_tests(self.app_home) if self.dist_version == '14.04': args, kwargs = subprocess.check_call.call_args if self.dist_version == '16.04': args, kwargs = subprocess.run.call_args self.assertTrue(isinstance(kwargs['stderr'], io.TextIOWrapper), kwargs['stderr']) log_file_regex = re.compile('%s/test_results/test_\d{8}-\d{6}\.log' % os.path.dirname(self.log_file)) self.assertTrue( log_file_regex.match(kwargs['stderr'].name), kwargs['stderr'].name )
def test_requirements_are_correctly_read(self): """" tests read_reqs returns correct structure """ reqs_list = [ ['biopython', '1.66'], ['cssselect', '0.9.1'], ['Django', '1.9.5'], ['django-debug-toolbar', '1.4'], ['django-with-asserts', '0.0.1'], ['lxml', '3.6.0'], ['numpy', '1.11.0'], ['psycopg2', '2.6.1'], ['requests', '2.9.1'], ['sqlparse', '0.1.19'], ] install_django_app = InstallDjangoApp(self.dist_version, self.log_file, self.log_level, venv=self.venv) reqs = install_django_app.read_reqs(self.reqs_file) self.assertEqual(reqs_list, reqs, format(reqs))
def test_copy_config_does_nothing_when_config_files_are_already_present_in_app(self): """ tests that copy_config does nothing when config files are already present in app """ conf = [ {'file': 'settings.json', 'move_to': os.path.join(self.app_home, self.app_name)}, {'file': '%s_uwsgi.ini' % self.app_name, 'move_to': self.app_home} ] os.makedirs(os.path.join(self.app_home, self.app_name, self.app_name)) for f in conf: with open(os.path.join(f['move_to'], f['file']), 'w') as file: file.write('%s file\n' % f['file']) install_django_app = InstallDjangoApp( self.dist_version, self.log_file, self.log_level, venv=self.venv, git_repo=self.git_repo ) install_django_app.copy_config(self.app_home) for f in conf: self.log('INFO: %s is already present in %s' % (f['file'], self.app_name))
def test_add_app_to_path(self): """ tests that app is added to python path and message is logged """ if self.dist_version == '14.04': self.python_version = 'python3.4' elif self.dist_version == '16.04': self.python_version = 'python3.5' os.makedirs(os.path.join(self.venv, 'lib', self.python_version, 'site-packages')) install_django_app = InstallDjangoApp( self.dist_version, self.log_file, self.log_level, venv=self.venv, git_repo=self.git_repo ) install_django_app.add_app_to_path(self.app_home) pth = os.path.join(self.venv, 'lib', self.python_version, 'site-packages', 'app_name.pth') msg = '%s has been added to python path in %s' % (self.app_name, self.venv) with open(pth) as pth_file: pth_list = [l for l in pth_file] self.assertEqual(['%s\n' % os.path.join(self.app_home, self.app_name)], pth_list, pth_list) self.log('INFO: %s' % msg)
def test_stop_uwsgi(self, check_process_mock): """ tests that stop_uwsgi writes to fifo and writes to log """ djangoapp.FIFO_DIR = self.fifo_dir mocks.alt_bool = Alternate([True]) os.makedirs(os.path.join(self.fifo_dir, self.app_name)) install_django_app = InstallDjangoApp(self.dist_version, self.log_file, self.log_level, git_repo=self.git_repo, fifo_dir=self.fifo_dir ) install_django_app.stop_uwsgi() with open(os.path.join(self.fifo_dir, 'fifo0')) as fifo: fifo_list = [l for l in fifo] self.assertEqual(['q'], fifo_list, fifo_list) self.log('INFO: stopped uwsgi server') self.assertEqual( [call('uwsgi')], check_process_mock.mock_calls, check_process_mock.mock_calls )
def test_remove_app(self): """ tests that remove_app removes all files in app """ user = getpass.getuser() clone_app_mock(self.app_home) site_files = [ os.path.join(self.app_home, self.app_name, 'static/static_file'), os.path.join(self.app_home, self.app_name, 'media/media_file'), os.path.join(self.app_home, '%s_uwsgi_params' % self.app_name), os.path.join(self.app_home, self.app_name, 'static/base/site_down/index.html'), os.path.join(self.app_home, self.app_name) ] install_django_app = InstallDjangoApp( self.dist_version, self.log_file, self.log_level, venv=self.venv, git_repo=self.git_repo, ) install_django_app.remove_app(self.app_home, user) for s in site_files: self.assertFalse(os.path.exists(s), s) self.log('INFO: removed %s' % self.app_name) self.assertTrue(os.path.exists(self.app_home))
def test_install_sys_deps(self): """ tests install_sys_deps calls apt-get install command, exits on error and writes to log """ if self.dist_version == '14.04': self.python_version = 'python3.4' elif self.dist_version == '16.04': self.python_version = 'python3.5' install_django_app = InstallDjangoApp(self.dist_version, self.log_file, self.log_level, venv=self.venv) deps = install_django_app.read_sys_deps(self.sys_deps_file) cmd = ['apt-get', 'install', '-y', 'libpq-dev', 'python3-numpy', 'libxml2-dev', 'libxslt1-dev', 'zlib1g-dev'] msg = 'successfully installed: libpq-dev python3-numpy libxml2-dev libxslt1-dev zlib1g-dev' func = 'install_sys_deps' args = (deps,) self.run_success([cmd], [msg], func, install_django_app.install_sys_deps, args) self.run_error(cmd, func, install_django_app.install_sys_deps, args)
def test_install_app(self, copy_config_mock, add_app_to_path_mock): """ tests install_app runs commands and writes to log """ biopython_reqs = 'numpy==1.11.0' user = getpass.getuser() install_django_app = InstallDjangoApp( self.dist_version, self.log_file, self.log_level, venv=self.venv, git_repo=self.git_repo ) ret = install_django_app.install_app(self.app_home, user, self.sys_deps_file, self.reqs_file) cmds = [ ['git', 'clone', self.git_repo], [self.pip, 'install', biopython_reqs], [ self.pip, 'install', 'biopython==1.66', 'cssselect==0.9.1', 'Django==1.9.5', 'django-debug-toolbar==1.4', 'django-with-asserts==0.0.1', 'lxml==3.6.0', 'numpy==1.11.0', 'psycopg2==2.6.1', 'requests==2.9.1', 'sqlparse==0.1.19'], ['apt-get', 'install', '-y', 'libpq-dev', 'python3-numpy', 'libxml2-dev', 'libxslt1-dev', 'zlib1g-dev'], ] if self.dist_version == '14.04': calls = [args for args, kwargs in subprocess.check_call.call_args_list] cmds.append(['virtualenv', '-p', '/usr/bin/python3.4', self.venv]) else: if self.dist_version == '16.04': calls = [args for args, kwargs in subprocess.run.call_args_list] cmds.append(['pyvenv', self.venv]) self.assertEqual(0, ret, str(ret)) for cmd in cmds: self.assertTrue((cmd,) in calls, calls) msgs = [ 'INFO: successfully cloned app_name to %s' % self.app_home, 'INFO: successfully created virtualenv %s' % VENV, 'INFO: successfully installed: numpy==1.11.0', 'INFO: successfully installed: biopython(1.66) cssselect(0.9.1) Django(1.9.5) django-debug-toolbar(1.4) ' 'django-with-asserts(0.0.1) lxml(3.6.0) numpy(1.11.0) psycopg2(2.6.1) requests(2.9.1) sqlparse(0.1.19)', 'INFO: successfully installed: libpq-dev python3-numpy libxml2-dev libxslt1-dev zlib1g-dev', 'INFO: changed ownership of %s to %s:%s' % (self.app_home, user, user), 'INFO: changed permissions of %s files to 400 and directories to 500' % self.app_home, 'INFO: changed ownership of %s to %s:%s' % (os.path.dirname(self.venv), user, user), 'INFO: changed permissions of %s to %s' % (os.path.dirname(self.venv), '500'), 'INFO: install django app exited with code 0' ] for m in msgs: self.log(m) self.assertEqual([call(self.app_home, uwsgi=True)], copy_config_mock.mock_calls, copy_config_mock.mock_calls) self.assertEqual([call(self.app_home)], add_app_to_path_mock.mock_calls, add_app_to_path_mock.mock_calls)