class ConfigServiceUpdateConfigTest(unittest.TestCase): def setUp(self): super().setUp() test_utils.setup() authorizer = Authorizer([], ['admin_user', 'admin_non_editor'], [], ['admin_user'], EmptyGroupProvider()) self.admin_user = User('admin_user', {}) self.config_service = ConfigService(authorizer, test_utils.temp_folder) for suffix in 'XYZ': name = 'Conf ' + suffix _create_script_config_file('conf' + suffix, name=name, script_path=_default_script_path(name)) _create_script_file(name, suffix) def tearDown(self): super().tearDown() test_utils.cleanup() def test_update_simple_config(self): config = _prepare_script_config_object( 'Conf X', description='My wonderful test config') self.config_service.update_config(self.admin_user, config, 'confX.json', None) _validate_config(self, 'confX.json', config) def test_save_another_name(self): config = _prepare_script_config_object( 'Conf A', description='My wonderful test config') self.config_service.update_config(self.admin_user, config, 'confX.json', None) _validate_config(self, 'confX.json', config) configs_path = os.path.join(test_utils.temp_folder, 'runners') self.assertEqual(3, len(os.listdir(configs_path))) def test_non_admin_access(self): config = _prepare_script_config_object( 'conf1', description='My wonderful test config') self.assertRaises(AdminAccessRequiredException, self.config_service.update_config, User('my_user', {}), config, 'confX.json', None) def test_blank_name(self): config = _prepare_script_config_object( ' ', description='My wonderful test config') self.assertRaises(InvalidConfigException, self.config_service.update_config, self.admin_user, config, 'confX.json', None) def test_strip_name(self): config = _prepare_script_config_object( ' Conf X ', description='My wonderful test config') self.config_service.update_config(self.admin_user, config, 'confX.json', None) config['name'] = 'Conf X' _validate_config(self, 'confX.json', config) def test_blank_script_path(self): config = _prepare_script_config_object( 'Conf X', description='My wonderful test config', script=script_path('')) self.assertRaises(InvalidConfigException, self.config_service.update_config, self.admin_user, config, 'confX.json', None) def test_strip_script_path(self): config = _prepare_script_config_object( 'Conf X', description='My wonderful test config', script=script_path(' my_script.sh\t \t')) self.config_service.update_config(self.admin_user, config, 'confX.json', None) config['script_path'] = 'my_script.sh' _validate_config(self, 'confX.json', config) def test_name_already_exists(self): config = _prepare_script_config_object( 'Conf Y', description='My wonderful test config') self.assertRaisesRegex( InvalidConfigException, 'Another script found with the same name: Conf Y', self.config_service.update_config, self.admin_user, config, 'confX.json', None) def test_blank_filename(self): config = _prepare_script_config_object( 'Conf X', description='My wonderful test config') self.assertRaises(InvalidConfigException, self.config_service.update_config, self.admin_user, config, ' ', None) def test_filename_not_exists(self): config = _prepare_script_config_object( 'Conf X', description='My wonderful test config') self.assertRaisesRegex(InvalidFileException, 'Failed to find script path', self.config_service.update_config, self.admin_user, config, 'conf A.json', None) def test_filename_already_exists(self): config = _prepare_script_config_object( 'Conf Y', description='My wonderful test config') self.assertRaisesRegex( InvalidConfigException, 'Another script found with the same name: Conf Y', self.config_service.update_config, self.admin_user, config, 'confX.json', None) def test_update_sorted_values(self): config = _prepare_script_config_object('Conf X', requires_terminal=False, parameters=[{ 'name': 'param1' }], description='Some description', include='included', allowed_users=[], script=script_path('cd ~')) self.config_service.update_config(self.admin_user, config, 'confX.json', None) body = OrderedDict([('name', 'Conf X'), ('script_path', 'cd ~'), ('description', 'Some description'), ('allowed_users', []), ('include', 'included'), ('requires_terminal', False), ('parameters', [{ 'name': 'param1' }])]) _validate_config(self, 'confX.json', body) def test_update_config_allowed_admin_user(self): config = _prepare_script_config_object( 'Conf X', description='My wonderful test config', admin_users=['admin_user']) self.config_service.update_config(self.admin_user, config, 'confX.json', None) new_config = _prepare_script_config_object('Conf X', description='New desc') self.config_service.update_config(self.admin_user, new_config, 'confX.json', None) _validate_config(self, 'confX.json', new_config) @parameterized.expand([('Conf X', ), ('Conf X111', )]) def test_update_config_different_admin_user(self, new_name): config = _prepare_script_config_object( 'Conf X', description='My wonderful test config', admin_users=['another_user']) self.config_service.update_config(self.admin_user, config, 'confX.json', None) new_config = _prepare_script_config_object(new_name, description='New desc', admin_users=['admin_user']) self.assertRaisesRegex(ConfigNotAllowedException, 'is not allowed to modify', self.config_service.update_config, self.admin_user, new_config, 'confX.json', None) _validate_config(self, 'confX.json', config) def test_update_config_new_code(self): config = _prepare_script_config_object('Conf X', script=new_code( 'abcdef', 'Conf X.sh')) self.config_service.update_config(self.admin_user, config, 'confX.json', None) _validate_config(self, 'confX.json', config) _validate_code(self, _default_script_path('Conf X'), 'abcdef') self.assertTrue(is_executable(_default_script_path('Conf X'))) def test_update_config_upload_code(self): config = _prepare_script_config_object( 'Conf X', script=upload_script('Conf X.sh')) body = bytes.fromhex('4D5A') self.config_service.update_config( self.admin_user, config, 'confX.json', HTTPFile(filename='whatever', body=body)) _validate_config(self, 'confX.json', config) _validate_code(self, _default_script_path('Conf X'), body) self.assertTrue(is_executable(_default_script_path('Conf X'))) @parameterized.expand([ (None, 'filename', 'abc', 'admin_user', InvalidConfigException, 'script option is required'), ('new_path', ' ', 'abc', 'admin_user', InvalidConfigException, 'script.path option is required'), ('new_code', 'Conf X.sh', 'abc', 'admin_non_editor', InvalidAccessException, 'not allowed to edit code'), ('upload_script', 'Conf X.sh', 'abc', 'admin_non_editor', InvalidAccessException, 'not allowed to edit code'), ('new_code', 'another.sh', 'abc', 'admin_user', InvalidConfigException, 'script.path override is not allowed'), ('upload_script', 'another.sh', 'abc', 'admin_user', InvalidConfigException, 'script.path override is not allowed'), ('new_code', 'Conf X.sh', None, 'admin_user', InvalidConfigException, 'script.code should be specified'), ('upload_script', 'Conf X.sh', None, 'admin_user', InvalidConfigException, 'Uploaded script should be specified'), ('some_mode', 'Conf X.sh', None, 'admin_user', InvalidConfigException, 'Unsupported mode'), ]) def test_update_config_script_update_exceptions(self, mode, filename, content, username, expected_exception, expected_message): body = None if mode == 'new_code': script = new_code(content, filename) elif mode == 'upload_script': script = upload_script(filename) body = HTTPFile(filename='whatever', body=content.encode('utf8')) if content else None elif mode == 'new_path': script = script_path(filename) elif mode is None: script = None else: script = {'mode': mode, 'path': filename} config = _prepare_script_config_object('Conf X', script=script) self.assertRaisesRegex(expected_exception, expected_message, self.config_service.update_config, User(username, {}), config, 'confX.json', body) @parameterized.expand([ ('new_code', ' ', InvalidFileException, 'Script path is not specified'), ('upload_script', ' ', InvalidFileException, 'Script path is not specified'), ('new_code', 'tests_temp/python', InvalidConfigException, 'Cannot edit binary file'), ('upload_script', 'tests_temp/python', None, None), ('new_code', 'tests_temp/python tests_temp/python', InvalidFileException, 'Cannot choose which binary file to edit'), ('upload_script', 'tests_temp/python tests_temp/python', InvalidFileException, 'Cannot choose which binary file to edit'), ('new_code', 'tests_temp/something.sh', InvalidConfigException, 'Script path does not exist'), ('upload_script', 'tests_temp/something.sh', None, None), ('upload_script', 'tests_temp/some thing.sh', InvalidFileException, 'Failed to find script path'), ('upload_script', '"tests_temp/some thing.sh"', None, None), ]) def test_update_config_script_update_when_code_loading_problems( self, mode, original_script_path, expected_exception, expected_message): copyfile(sys.executable, os.path.join(test_utils.temp_folder, 'python')) body = None if mode == 'new_code': script = { 'mode': 'new_code', 'code': 'abcdef', 'path': original_script_path if not is_blank(original_script_path) else 'anything' } elif mode == 'upload_script': script = { 'mode': 'upload_script', 'path': original_script_path if not is_blank(original_script_path) else 'anything' } body = HTTPFile(filename='whatever', body=b'xyz') else: script = None _create_script_config_file('ConfA', name='ConfA', script_path=original_script_path) config = _prepare_script_config_object('ConfA', script=script) if expected_exception is not None: self.assertRaisesRegex(expected_exception, expected_message, self.config_service.update_config, self.admin_user, config, 'ConfA.json', body) else: self.config_service.update_config(self.admin_user, config, 'ConfA.json', body)
class ConfigServiceUpdateConfigTest(unittest.TestCase): def setUp(self): super().setUp() test_utils.setup() authorizer = Authorizer([], ['admin_user'], EmptyGroupProvider()) self.admin_user = User('admin_user', {}) self.config_service = ConfigService(authorizer, test_utils.temp_folder) for suffix in 'XYZ': _create_script_config_file('conf' + suffix, name='Conf ' + suffix) def tearDown(self): super().tearDown() test_utils.cleanup() def test_update_simple_config(self): config = _prepare_script_config_object( 'Conf X', description='My wonderful test config') self.config_service.update_config(self.admin_user, config, 'confX.json') _validate_config(self, 'confX.json', config) def test_save_another_name(self): config = _prepare_script_config_object( 'Conf A', description='My wonderful test config') self.config_service.update_config(self.admin_user, config, 'confX.json') _validate_config(self, 'confX.json', config) configs_path = os.path.join(test_utils.temp_folder, 'runners') self.assertEqual(3, len(os.listdir(configs_path))) def test_non_admin_access(self): config = _prepare_script_config_object( 'conf1', description='My wonderful test config') self.assertRaises(AdminAccessRequiredException, self.config_service.update_config, User('my_user', {}), config, 'confX.json') def test_blank_name(self): config = _prepare_script_config_object( ' ', description='My wonderful test config') self.assertRaises(InvalidConfigException, self.config_service.update_config, self.admin_user, config, 'confX.json') def test_strip_name(self): config = _prepare_script_config_object( ' Conf X ', description='My wonderful test config') self.config_service.update_config(self.admin_user, config, 'confX.json') config['name'] = 'Conf X' _validate_config(self, 'confX.json', config) def test_blank_script_path(self): config = _prepare_script_config_object( 'Conf X', description='My wonderful test config') config['script_path'] = ' ' self.assertRaises(InvalidConfigException, self.config_service.update_config, self.admin_user, config, 'confX.json') def test_strip_script_path(self): config = _prepare_script_config_object( 'Conf X', description='My wonderful test config') config['script_path'] = ' my_script.sh\t \t' self.config_service.update_config(self.admin_user, config, 'confX.json') config['script_path'] = 'my_script.sh' _validate_config(self, 'confX.json', config) def test_name_already_exists(self): config = _prepare_script_config_object( 'Conf Y', description='My wonderful test config') self.assertRaisesRegex( InvalidConfigException, 'Another script found with the same name: Conf Y', self.config_service.update_config, self.admin_user, config, 'confX.json') def test_blank_filename(self): config = _prepare_script_config_object( 'Conf X', description='My wonderful test config') self.assertRaises(InvalidConfigException, self.config_service.update_config, self.admin_user, config, ' ') def test_filename_not_exists(self): config = _prepare_script_config_object( 'Conf X', description='My wonderful test config') self.assertRaisesRegex(InvalidFileException, 'Failed to find script path', self.config_service.update_config, self.admin_user, config, 'conf A.json') def test_filename_already_exists(self): config = _prepare_script_config_object( 'Conf Y', description='My wonderful test config') self.assertRaisesRegex( InvalidConfigException, 'Another script found with the same name: Conf Y', self.config_service.update_config, self.admin_user, config, 'confX.json') def test_update_sorted_values(self): config = _prepare_script_config_object('Conf X', requires_terminal=False, parameters=[{ 'name': 'param1' }], description='Some description', include='included', allowed_users=[], script_path='cd ~') self.config_service.update_config(self.admin_user, config, 'confX.json') body = OrderedDict([('name', 'Conf X'), ('script_path', 'cd ~'), ('description', 'Some description'), ('allowed_users', []), ('include', 'included'), ('requires_terminal', False), ('parameters', [{ 'name': 'param1' }])]) _validate_config(self, 'confX.json', body)