Example #1
0
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)