def setUp(self):
        super(CopytoolTestCase, self).setUp()

        from chroma_agent.config_store import ConfigStore

        self.mock_config = ConfigStore(tempfile.mkdtemp())
        patch("chroma_agent.copytool_monitor.config", self.mock_config).start()

        self.ct_id = "42"
        self.ct_bin_path = "/usr/sbin/lhsmtool_foo"
        self.ct_filesystem = "testfs"
        self.ct_mountpoint = "/mnt/testfs"
        self.ct_archive = 2
        self.ct_index = 0
        self.ct = Copytool(
            self.ct_id,
            self.ct_index,
            self.ct_bin_path,
            self.ct_archive,
            self.ct_filesystem,
            self.ct_mountpoint,
            "",
        )

        self.addCleanup(patch.stopall)
    def setUp(self):
        super(TestCopytoolManagement, self).setUp()

        from chroma_agent.config_store import ConfigStore
        self.mock_config = ConfigStore(tempfile.mkdtemp())
        mock.patch('chroma_agent.action_plugins.manage_copytool.config', self.mock_config).start()
        mock.patch('chroma_agent.copytool_monitor.config', self.mock_config).start()
        mock.patch('chroma_agent.action_plugins.settings_management.config', self.mock_config).start()

        mock.patch('chroma_agent.action_plugins.manage_copytool._write_service_init').start()

        self.mock_os_remove = mock.MagicMock()
        mock.patch('os.remove', self.mock_os_remove).start()

        from chroma_agent.action_plugins.settings_management import reset_agent_config
        reset_agent_config()

        self.ct_id = '42'
        self.ct_index = 0
        self.ct_archive = 1
        self.ct_bin_path = '/usr/sbin/lhsmtool_foo'
        self.ct_arguments = '-p /archive/testfs'
        self.ct_filesystem = 'testfs'
        self.ct_mountpoint = '/mnt/testfs'
        self._configure_copytool()
        self.ct_vars = _copytool_vars(self.ct_id)

        self.addCleanup(mock.patch.stopall)
Example #3
0
    def setUp(self):
        super(AgentStoreConversionTests, self).setUp()

        self.env_path_patch = patch("chroma_agent.conf.ENV_PATH",
                                    new=tempfile.mkdtemp())
        self.env_path = self.env_path_patch.start()
        self.config = ConfigStore(tempfile.mkdtemp())
class CopytoolTestCase(unittest.TestCase):
    def setUp(self):
        super(CopytoolTestCase, self).setUp()

        from chroma_agent.config_store import ConfigStore

        self.mock_config = ConfigStore(tempfile.mkdtemp())
        patch("chroma_agent.copytool_monitor.config", self.mock_config).start()

        self.ct_id = "42"
        self.ct_bin_path = "/usr/sbin/lhsmtool_foo"
        self.ct_filesystem = "testfs"
        self.ct_mountpoint = "/mnt/testfs"
        self.ct_archive = 2
        self.ct_index = 0
        self.ct = Copytool(
            self.ct_id,
            self.ct_index,
            self.ct_bin_path,
            self.ct_archive,
            self.ct_filesystem,
            self.ct_mountpoint,
            "",
        )

        self.addCleanup(patch.stopall)

    def tearDown(self):
        super(CopytoolTestCase, self).tearDown()

        shutil.rmtree(self.mock_config.path)

    def test_copytool_event_fifo(self):
        self.mock_config.set("settings", "agent",
                             {"copytool_fifo_directory": "/var/spool"})
        self.assertEqual(self.ct.event_fifo, "/var/spool/%s-events" % self.ct)

    def test_copytool_as_dict(self):
        self.assertDictEqual(
            self.ct.as_dict(),
            dict(
                id=self.ct.id,
                index=self.ct.index,
                bin_path=self.ct.bin_path,
                archive_number=self.ct.archive_number,
                filesystem=self.ct.filesystem,
                mountpoint=self.ct.mountpoint,
                hsm_arguments=self.ct.hsm_arguments,
            ),
        )
Example #5
0
    def setUp(self):
        super(ConfigStoreTests, self).setUp()

        self.config = ConfigStore(tempfile.mkdtemp())

        self.data = {
            'foo': 1,
            'bar': "1",
            'baz': ['qux', 'quux', 'corge'],
            'grault': {
                'garply': "waldo",
                'fred': ['plugh', 'xyzzy']
            },
            'thud': False
        }
Example #6
0
    def setUp(self):
        super(ConfigStoreTests, self).setUp()

        self.config = ConfigStore(tempfile.mkdtemp())

        self.data = {
            "foo": 1,
            "bar": "1",
            "baz": ["qux", "quux", "corge"],
            "grault": {
                "garply": "waldo",
                "fred": ["plugh", "xyzzy"]
            },
            "thud": False,
        }
Example #7
0
class AgentStoreConversionTests(unittest.TestCase):
    def setUp(self):
        super(AgentStoreConversionTests, self).setUp()

        self.config = ConfigStore(tempfile.mkdtemp())

    def tearDown(self):
        super(AgentStoreConversionTests, self).tearDown()

        shutil.rmtree(self.config.path)

    def _create_agentstore_config(self):
        import uuid
        import json
        import string

        self.old_server_conf = {'url': 'http://foo.bar.baz/'}

        with open(os.path.join(self.config.path, 'server_conf'), 'w') as f:
            json.dump(self.old_server_conf, f)

        self.old_target_configs = {}
        for i in xrange(0, 15):
            bdev = '/dev/sd%s' % string.ascii_lowercase[i]
            mntpt = '/mnt/target%04d' % i
            uuid_str = str(uuid.uuid4())
            target_config = dict(bdev=bdev, mntpt=mntpt)
            with open(os.path.join(self.config.path, uuid_str), 'w') as f:
                json.dump(target_config, f)
            self.old_target_configs[uuid_str] = target_config

    def test_agentstore_conversion(self):
        with patch('chroma_agent.action_plugins.settings_management.config',
                   new=self.config):
            self._create_agentstore_config()

            from chroma_agent.action_plugins.settings_management import _convert_agentstore_config
            _convert_agentstore_config()

            self.assertDictEqual(self.config.get('settings', 'server'),
                                 self.old_server_conf)

            for uuid, old_target_conf in self.old_target_configs.items():
                self.assertDictEqual(self.config.get('targets', uuid),
                                     old_target_conf)
Example #8
0
class AgentStoreConversionTests(unittest.TestCase):
    def setUp(self):
        super(AgentStoreConversionTests, self).setUp()

        self.env_path_patch = patch("chroma_agent.conf.ENV_PATH",
                                    new=tempfile.mkdtemp())
        self.env_path = self.env_path_patch.start()
        self.config = ConfigStore(tempfile.mkdtemp())

    def tearDown(self):
        super(AgentStoreConversionTests, self).tearDown()

        self.env_path_patch.stop()
        shutil.rmtree(self.env_path)
        shutil.rmtree(self.config.path)

    def _create_agentstore_config(self):
        import uuid
        import json
        import string

        self.old_server_conf = {"url": "http://foo.bar.baz/"}

        with open(os.path.join(self.config.path, "server_conf"), "w") as f:
            json.dump(self.old_server_conf, f)

        self.old_target_configs = {}
        for i in xrange(0, 15):
            bdev = "/dev/sd%s" % string.ascii_lowercase[i]
            mntpt = "/mnt/target%04d" % i
            uuid_str = str(uuid.uuid4())
            target_config = dict(bdev=bdev, mntpt=mntpt)
            with open(os.path.join(self.config.path, uuid_str), "w") as f:
                json.dump(target_config, f)
            self.old_target_configs[uuid_str] = target_config

    def test_agentstore_conversion(self):
        with patch("chroma_agent.action_plugins.settings_management.config",
                   new=self.config):
            self._create_agentstore_config()

            from chroma_agent.action_plugins.settings_management import (
                _convert_agentstore_config, )

            _convert_agentstore_config()

            with open(os.path.join(self.env_path, "manager-url.conf"),
                      "r") as f:
                self.assertEqual(
                    f.read(),
                    "IML_MANAGER_URL={}\n".format(
                        self.old_server_conf.get("url")),
                )

            for uuid, old_target_conf in self.old_target_configs.items():
                self.assertDictEqual(self.config.get("targets", uuid),
                                     old_target_conf)
Example #9
0
class CopytoolTestCase(unittest.TestCase):
    def setUp(self):
        super(CopytoolTestCase, self).setUp()

        from chroma_agent.config_store import ConfigStore
        self.mock_config = ConfigStore(tempfile.mkdtemp())
        patch('chroma_agent.copytool_monitor.config', self.mock_config).start()

        self.ct_id = '42'
        self.ct_bin_path = '/usr/sbin/lhsmtool_foo'
        self.ct_filesystem = 'testfs'
        self.ct_mountpoint = '/mnt/testfs'
        self.ct_archive = 2
        self.ct_index = 0
        self.ct = Copytool(self.ct_id, self.ct_index, self.ct_bin_path,
                           self.ct_archive, self.ct_filesystem,
                           self.ct_mountpoint, "")

        self.addCleanup(patch.stopall)

    def tearDown(self):
        super(CopytoolTestCase, self).tearDown()

        shutil.rmtree(self.mock_config.path)

    def test_copytool_event_fifo(self):
        self.mock_config.set('settings', 'agent',
                             {'copytool_fifo_directory': '/var/spool'})
        self.assertEqual(self.ct.event_fifo, '/var/spool/%s-events' % self.ct)

    def test_copytool_as_dict(self):
        self.assertDictEqual(
            self.ct.as_dict(),
            dict(id=self.ct.id,
                 index=self.ct.index,
                 bin_path=self.ct.bin_path,
                 archive_number=self.ct.archive_number,
                 filesystem=self.ct.filesystem,
                 mountpoint=self.ct.mountpoint,
                 hsm_arguments=self.ct.hsm_arguments))
class TestCopytoolManagement(CommandCaptureTestCase, AgentUnitTestCase):
    def setUp(self):
        super(TestCopytoolManagement, self).setUp()

        from chroma_agent.config_store import ConfigStore
        self.mock_config = ConfigStore(tempfile.mkdtemp())
        mock.patch('chroma_agent.action_plugins.manage_copytool.config', self.mock_config).start()
        mock.patch('chroma_agent.copytool_monitor.config', self.mock_config).start()
        mock.patch('chroma_agent.action_plugins.settings_management.config', self.mock_config).start()

        mock.patch('chroma_agent.action_plugins.manage_copytool._write_service_init').start()

        self.mock_os_remove = mock.MagicMock()
        mock.patch('os.remove', self.mock_os_remove).start()

        from chroma_agent.action_plugins.settings_management import reset_agent_config
        reset_agent_config()

        self.ct_id = '42'
        self.ct_index = 0
        self.ct_archive = 1
        self.ct_bin_path = '/usr/sbin/lhsmtool_foo'
        self.ct_arguments = '-p /archive/testfs'
        self.ct_filesystem = 'testfs'
        self.ct_mountpoint = '/mnt/testfs'
        self._configure_copytool()
        self.ct_vars = _copytool_vars(self.ct_id)

        self.addCleanup(mock.patch.stopall)

    def tearDown(self):
        super(TestCopytoolManagement, self).tearDown()

        mock.patch.stopall()

        shutil.rmtree(self.mock_config.path)

    def _configure_copytool(self):
        self.ct_id = configure_copytool(self.ct_id,
                                       self.ct_index,
                                       self.ct_bin_path,
                                       self.ct_archive,
                                       self.ct_filesystem,
                                       self.ct_mountpoint,
                                       self.ct_arguments)

    def test_start_monitored_copytool(self):
        self.single_commands(CommandCaptureCommand(('systemctl', 'daemon-reload')),
                             CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-monitor-%s' % self.ct_id), rc=1),
                             CommandCaptureCommand(('systemctl', 'start', 'chroma-copytool-monitor-%s' % self.ct_id)),
                             CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-monitor-%s' % self.ct_id)),
                             CommandCaptureCommand(('systemctl', 'daemon-reload')),
                             CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-%s' % self.ct_id), rc=1),
                             CommandCaptureCommand(('systemctl', 'start', 'chroma-copytool-%s' % self.ct_id)),
                             CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-%s' % self.ct_id)))

        self.assertAgentOK(start_monitored_copytool(self.ct_id))
        self.assertRanAllCommandsInOrder()

    def test_stop_monitored_copytool(self):
        self.single_commands(CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-monitor-%s' % self.ct_id)),
                             CommandCaptureCommand(('systemctl', 'stop', 'chroma-copytool-monitor-%s' % self.ct_id)),
                             CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-monitor-%s' % self.ct_id), rc=1),
                             CommandCaptureCommand(('systemctl', 'daemon-reload')),
                             CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-%s' % self.ct_id)),
                             CommandCaptureCommand(('systemctl', 'stop', 'chroma-copytool-%s' % self.ct_id)),
                             CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-%s' % self.ct_id), rc=1),
                             CommandCaptureCommand(('systemctl', 'daemon-reload')))

        with mock.patch('os.path.exists', return_value=True):
            self.assertAgentOK(stop_monitored_copytool(self.ct_id))

        self.assertRanAllCommandsInOrder()
        self.assertEqual(self.mock_os_remove.call_count, 2)
        self.mock_os_remove.assert_called_with('/etc/init.d/chroma-copytool-%s' % self.ct_id)

    def test_start_should_be_idempotent(self):
        self.single_commands(CommandCaptureCommand(('systemctl', 'daemon-reload')),
                             CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-monitor-%s' % self.ct_id)),
                             CommandCaptureCommand(('systemctl', 'stop', 'chroma-copytool-monitor-%s' % self.ct_id)),
                             CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-monitor-%s' % self.ct_id), rc=1),
                             CommandCaptureCommand(('systemctl', 'start', 'chroma-copytool-monitor-%s' % self.ct_id)),
                             CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-monitor-%s' % self.ct_id)),
                             CommandCaptureCommand(('systemctl', 'daemon-reload')),
                             CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-%s' % self.ct_id)),
                             CommandCaptureCommand(('systemctl', 'stop', 'chroma-copytool-%s' % self.ct_id)),
                             CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-%s' % self.ct_id), rc=1),
                             CommandCaptureCommand(('systemctl', 'start', 'chroma-copytool-%s' % self.ct_id)),
                             CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-%s' % self.ct_id)))

        self.assertAgentOK(start_monitored_copytool(self.ct_id))
        self.assertRanAllCommandsInOrder()

    def test_stop_should_be_idempotent1(self):
        self.single_commands(CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-monitor-%s' % self.ct_id)),
                             CommandCaptureCommand(('systemctl', 'stop', 'chroma-copytool-monitor-%s' % self.ct_id)),
                             CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-monitor-%s' % self.ct_id), rc=1),
                             CommandCaptureCommand(('systemctl', 'daemon-reload')),
                             CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-%s' % self.ct_id)),
                             CommandCaptureCommand(('systemctl', 'stop', 'chroma-copytool-%s' % self.ct_id)),
                             CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-%s' % self.ct_id), rc=1),
                             CommandCaptureCommand(('systemctl', 'daemon-reload')),
                             CommandCaptureCommand(('systemctl', 'daemon-reload')),
                             CommandCaptureCommand(('systemctl', 'daemon-reload')))

        with mock.patch('os.path.exists', return_value=True):
            self.assertAgentOK(stop_monitored_copytool(self.ct_id))

        with mock.patch('os.path.exists', return_value=False):
            self.assertAgentOK(stop_monitored_copytool(self.ct_id))

        self.assertRanAllCommandsInOrder()

    def test_stop_should_be_idempotent2(self):
        self.single_commands(CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-monitor-%s' % self.ct_id), rc=1),
                             CommandCaptureCommand(('systemctl', 'daemon-reload')),
                             CommandCaptureCommand(('systemctl', 'is-active', 'chroma-copytool-%s' % self.ct_id), rc=1),
                             CommandCaptureCommand(('systemctl', 'daemon-reload')))

        with mock.patch('os.path.exists', return_value=True):
            self.assertAgentOK(stop_monitored_copytool(self.ct_id))

        self.assertRanAllCommandsInOrder()

    def test_configure_should_be_idempotent(self):
        expected_kwargs = dict(
            index = self.ct_index,
            bin_path = self.ct_bin_path,
            filesystem = self.ct_filesystem,
            mountpoint = self.ct_mountpoint,
            archive_number = self.ct_archive,
            hsm_arguments = self.ct_arguments
        )
        with mock.patch('chroma_agent.action_plugins.manage_copytool.update_copytool') as patched_update_copytool:
            self._configure_copytool()
            patched_update_copytool.assert_called_with(self.ct_id, **expected_kwargs)

    @mock.patch('chroma_agent.action_plugins.manage_copytool.stop_monitored_copytool')
    def test_unconfigure_copytool(self, stop_monitored_copytool):
        # NB: configure_copytool is implicitly tested numerous times as
        # part of setUp(). Kind of hacky but whatever.
        unconfigure_copytool(self.ct_id)
        stop_monitored_copytool.assert_called_with(self.ct_id)

    @mock.patch('chroma_agent.action_plugins.manage_copytool.stop_monitored_copytool')
    @mock.patch('chroma_agent.action_plugins.manage_copytool.start_monitored_copytool')
    def test_update_copytool(self, start_monitored_copytool, stop_monitored_copytool):
        update_copytool(self.ct_id, archive_number=2)

        stop_monitored_copytool.assert_called_with(self.ct_id)

        self.assertEquals(self.mock_config.get('copytools', self.ct_id)['archive_number'], 2)

        start_monitored_copytool.assert_called_with(self.ct_id)

    def test_list_copytools(self):
        self.assertDictEqual(list_copytools(), {'raw_result': self.ct_id})
Example #11
0
    def setUp(self):
        super(ApiTestCaseWithTestReset, self).setUp()

        if config.get('simulator', False):
            # When we're running with the simulator, parts of the simulated
            # Copytools use agent code, and the agent code expects to find
            # a populated agent-side configuration. The safe way to handle
            # this requirement is to use mock to patch in a fresh
            # ConfigStore instance for each test run.
            try:
                from chroma_agent.config_store import ConfigStore
            except ImportError:
                raise ImportError(
                    "Cannot import agent, do you need to do a 'setup.py develop' of it?"
                )

            import mock  # Mock is only available when running the simulator, hence local inclusion
            self.mock_config = ConfigStore(tempfile.mkdtemp())
            mock.patch('chroma_agent.config', self.mock_config).start()
            from chroma_agent.action_plugins.settings_management import reset_agent_config, set_agent_config
            reset_agent_config()
            # Allow the worker to create a fifo in /tmp rather than /var/spool
            set_agent_config('copytool_fifo_directory',
                             self.COPYTOOL_TESTING_FIFO_ROOT)

            try:
                from cluster_sim.simulator import ClusterSimulator
            except ImportError:
                raise ImportError(
                    "Cannot import simulator, do you need to do a 'setup.py develop' of it?"
                )

            # The simulator's state directory will be left behind when a test fails,
            # so make sure it has a unique-per-run name
            timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H%M%S")
            state_path = 'simulator_state_%s.%s_%s' % (
                self.__class__.__name__, self._testMethodName, timestamp)
            if os.path.exists(state_path):
                raise RuntimeError(
                    "Simulator state folder already exists at '%s'!" %
                    state_path)

            # Hook up the agent log to a file
            from chroma_agent.agent_daemon import daemon_log
            handler = logging.FileHandler(
                os.path.join(config.get('log_dir', '/var/log/'),
                             'chroma_test_agent.log'))
            handler.setFormatter(
                logging.Formatter('[%(asctime)s] %(message)s',
                                  '%d/%b/%Y:%H:%M:%S'))
            daemon_log.addHandler(handler)
            daemon_log.setLevel(logging.DEBUG)

            self.simulator = ClusterSimulator(
                state_path, config['chroma_managers'][0]['server_http_url'])
            volume_count = max(
                [len(s['device_paths']) for s in self.config_servers])
            self.simulator.setup(len(self.config_servers),
                                 len(self.config_workers),
                                 volume_count,
                                 self.SIMULATOR_NID_COUNT,
                                 self.SIMULATOR_CLUSTER_SIZE,
                                 len(config['power_distribution_units']),
                                 su_size=0)
            self.remote_operations = SimulatorRemoteOperations(
                self, self.simulator)
            if self.TESTS_NEED_POWER_CONTROL:
                self.simulator.power.start()
        else:
            self.remote_operations = RealRemoteOperations(self)

        if self.quick_setup is False:
            # Ensure that all servers are up and available
            for server in self.TEST_SERVERS:
                logger.info(
                    "Checking that %s is running and restarting if necessary..."
                    % server['fqdn'])
                self.remote_operations.await_server_boot(server['fqdn'],
                                                         restart=True)
                logger.info("%s is running" % server['fqdn'])
                self.remote_operations.inject_log_message(
                    server['fqdn'], "==== "
                    "starting test %s "
                    "=====" % self)

            if config.get('reset', True):
                self.reset_cluster()
            elif config.get('soft_reset', True):
                # Reset the manager via the API
                self.wait_until_true(self.api_contactable)
                self.remote_operations.unmount_clients()
                self.api_force_clear()
                self.remote_operations.clear_ha(self.TEST_SERVERS)
                self.remote_operations.clear_lnet_config(self.TEST_SERVERS)

            if config.get('managed'):
                # Ensure that config from previous runs doesn't linger into
                # this one.
                self.remote_operations.remove_config(self.TEST_SERVERS)

                # If there are no configuration options for a given server
                # (e.g. corosync_config), then this is a noop and no config file
                # is written.
                self.remote_operations.write_config(self.TEST_SERVERS)

                # cleanup linux devices
                self.cleanup_linux_devices(self.TEST_SERVERS)

                # cleanup zfs pools
                self.cleanup_zfs_pools(
                    self.config_servers, self.CZP_EXPORTPOOLS |
                    (self.CZP_RECREATEZPOOLS if config.get(
                        'new_zpools_each_test', False) else
                     self.CZP_REMOVEDATASETS), None, True)

            # Enable agent debugging
            self.remote_operations.enable_agent_debug(self.TEST_SERVERS)

        self.wait_until_true(self.supervisor_controlled_processes_running)
        self.initial_supervisor_controlled_process_start_times = self.get_supervisor_controlled_process_start_times(
        )
Example #12
0
    def setUp(self):
        super(AgentStoreConversionTests, self).setUp()

        self.config = ConfigStore(tempfile.mkdtemp())
Example #13
0
class ConfigStoreTests(unittest.TestCase):
    def setUp(self):
        super(ConfigStoreTests, self).setUp()

        self.config = ConfigStore(tempfile.mkdtemp())

        self.data = {
            'foo': 1,
            'bar': "1",
            'baz': ['qux', 'quux', 'corge'],
            'grault': {
                'garply': "waldo",
                'fred': ['plugh', 'xyzzy']
            },
            'thud': False
        }

    def tearDown(self):
        super(ConfigStoreTests, self).tearDown()

        shutil.rmtree(self.config.path)

    def test_set(self):
        self.config.set("barfy", "cow", self.data)
        self.assertEqual(self.data, self.config.get("barfy", "cow"))

        with self.assertRaises(ConfigKeyExistsError):
            self.config.set("barfy", "cow", self.data)

    def test_update(self):
        self.config.set("barfy", "cow", self.data)

        self.data['thud'] = True
        self.config.update("barfy", "cow", self.data)
        self.assertEqual(self.data, self.config.get("barfy", "cow"))

    def test_delete(self):
        self.config.set("barfy", "cow", self.data)

        self.config.delete("barfy", "cow")
        with self.assertRaises(KeyError):
            self.config.get("barfy", "cow")

    def test_delete_idempotent(self):
        # Shouldn't fail -- if it's not there, then the intended goal
        # was accomplished.
        self.config.delete("barfy", "cow")

    def test_delete_section(self):
        self.config.set("barfy", "cow", self.data)

        self.config.delete_section("barfy")
        with self.assertRaises(TypeError):
            self.config.get("barfy", "cow")

    def test_get_nonexistent_section(self):
        self.assertListEqual([], self.config.get_section_keys('foo'))
        self.assertDictEqual({}, self.config.get_section('foo'))

    def test_sections(self):
        maladies = ["barfy", "gassy", "sad", "grumpy"]
        for malady in maladies:
            self.config.set(malady, "cow", self.data)

        self.assertListEqual(sorted(maladies), self.config.sections)

    def test_get_section(self):
        self.config.set("barfy", "cow", self.data)

        self.assertDictEqual({'cow': self.data},
                             self.config.get_section("barfy"))

    def test_get_all(self):
        maladies = ["barfy", "gassy", "sad", "grumpy"]
        for malady in maladies:
            self.config.set(malady, "cow", self.data)

        self.assertDictEqual(
            {
                'barfy': {
                    'cow': self.data
                },
                'gassy': {
                    'cow': self.data
                },
                'sad': {
                    'cow': self.data
                },
                'grumpy': {
                    'cow': self.data
                }
            }, self.config.get_all())

    def test_clear(self):
        maladies = ["barfy", "gassy", "sad", "grumpy"]
        for malady in maladies:
            self.config.set(malady, "cow", self.data)

        self.config.clear()
        self.assertListEqual([], self.config.sections)

    def test_bad_identifiers(self):
        badkey = object()
        with self.assertRaises(InvalidConfigIdentifier):
            self.config.set('whoops', badkey, "foobar")
        with self.assertRaises(InvalidConfigIdentifier):
            self.config.set(badkey, 'whoops', "foobar")

    def test_unicode_identifiers(self):
        test_id = u'should work'
        self.config.set('ok', test_id, self.data)
        self.assertDictEqual(self.data, self.config.get('ok', test_id))
        self.config.set(test_id, 'ok', self.data)
        self.assertDictEqual(self.data, self.config.get(test_id, 'ok'))

    def test_thread_safety(self):
        import Queue
        config = self.config
        data = self.data
        testcase = self
        exceptions = Queue.Queue()

        class ThreadA(threading.Thread):
            def __init__(self):
                super(ThreadA, self).__init__()
                self.config = config
                self.data = data
                self.testcase = testcase

            def run(self):
                try:
                    with self.config.lock:
                        self.config.set("barfy", "cow", self.data)
                        time.sleep(1)
                        self.testcase.assertDictEqual(
                            self.data, self.config.get("barfy", "cow"))
                except Exception as e:
                    exceptions.put(e)

        class ThreadB(threading.Thread):
            def __init__(self):
                super(ThreadB, self).__init__()
                self.config = config

            def run(self):
                try:
                    self.config.clear()
                except Exception as e:
                    exceptions.put(e)

        a = ThreadA()
        b = ThreadB()
        self.assertEqual(a.config, b.config)

        a.start()
        b.start()

        a.join()
        b.join()

        with self.assertRaises(Queue.Empty):
            raise RuntimeError("Thread safety check failed: %s" %
                               exceptions.get(block=False))

    def test_multiprocess_safety(self):
        from multiprocessing import Queue
        from Queue import Empty
        config = self.config
        data = self.data
        testcase = self
        exceptions = Queue()

        class ProcessA(multiprocessing.Process):
            def __init__(self):
                super(ProcessA, self).__init__()
                self.config = config
                self.data = data
                self.testcase = testcase

            def run(self):
                try:
                    with self.config.lock:
                        self.config.set("barfy", "cow", self.data)
                        time.sleep(1)
                        self.testcase.assertDictEqual(
                            self.data, self.config.get("barfy", "cow"))
                except Exception as e:
                    exceptions.put(e)

        class ProcessB(multiprocessing.Process):
            def __init__(self):
                super(ProcessB, self).__init__()
                self.config = config

            def run(self):
                try:
                    self.config.clear()
                except Exception as e:
                    exceptions.put(e)

        a = ProcessA()
        b = ProcessB()
        self.assertEqual(a.config, b.config)

        a.start()
        b.start()

        a.join()
        b.join()

        with self.assertRaises(Empty):
            raise RuntimeError("Multi-process safety check failed: %s" %
                               exceptions.get(block=False))

    def test_profile_managed_true(self):
        self.config.set('settings', 'profile', {'managed': True})
        self.assertEqual(self.config.profile_managed, True)

    def test_profile_managed_false(self):
        self.config.set('settings', 'profile', {'managed': False})
        self.assertEqual(self.config.profile_managed, False)

    def test_profile_managed_missing_false_section(self):
        self.assertEqual(self.config.profile_managed, False)

    def test_profile_managed_missing_false_ket(self):
        self.config.set('settings', 'profile', {'trevor': 'andy'})
        self.assertEqual(self.config.profile_managed, False)
Example #14
0
class ConfigStoreTests(unittest.TestCase):
    def setUp(self):
        super(ConfigStoreTests, self).setUp()

        self.config = ConfigStore(tempfile.mkdtemp())

        self.data = {
            "foo": 1,
            "bar": "1",
            "baz": ["qux", "quux", "corge"],
            "grault": {
                "garply": "waldo",
                "fred": ["plugh", "xyzzy"]
            },
            "thud": False,
        }

    def tearDown(self):
        super(ConfigStoreTests, self).tearDown()

        shutil.rmtree(self.config.path)

    def test_set(self):
        self.config.set("barfy", "cow", self.data)
        self.assertEqual(self.data, self.config.get("barfy", "cow"))

        with self.assertRaises(ConfigKeyExistsError):
            self.config.set("barfy", "cow", self.data)

    def test_update(self):
        self.config.set("barfy", "cow", self.data)

        self.data["thud"] = True
        self.config.update("barfy", "cow", self.data)
        self.assertEqual(self.data, self.config.get("barfy", "cow"))

    def test_delete(self):
        self.config.set("barfy", "cow", self.data)

        self.config.delete("barfy", "cow")
        with self.assertRaises(KeyError):
            self.config.get("barfy", "cow")

    def test_delete_idempotent(self):
        # Shouldn't fail -- if it's not there, then the intended goal
        # was accomplished.
        self.config.delete("barfy", "cow")

    def test_delete_section(self):
        self.config.set("barfy", "cow", self.data)

        self.config.delete_section("barfy")
        with self.assertRaises(TypeError):
            self.config.get("barfy", "cow")

    def test_get_nonexistent_section(self):
        self.assertListEqual([], self.config.get_section_keys("foo"))
        self.assertDictEqual({}, self.config.get_section("foo"))

    def test_sections(self):
        maladies = ["barfy", "gassy", "sad", "grumpy"]
        for malady in maladies:
            self.config.set(malady, "cow", self.data)

        self.assertListEqual(sorted(maladies), self.config.sections)

    def test_get_section(self):
        self.config.set("barfy", "cow", self.data)

        self.assertDictEqual({"cow": self.data},
                             self.config.get_section("barfy"))

    def test_get_all(self):
        maladies = ["barfy", "gassy", "sad", "grumpy"]
        for malady in maladies:
            self.config.set(malady, "cow", self.data)

        self.assertDictEqual(
            {
                "barfy": {
                    "cow": self.data
                },
                "gassy": {
                    "cow": self.data
                },
                "sad": {
                    "cow": self.data
                },
                "grumpy": {
                    "cow": self.data
                },
            },
            self.config.get_all(),
        )

    def test_clear(self):
        maladies = ["barfy", "gassy", "sad", "grumpy"]
        for malady in maladies:
            self.config.set(malady, "cow", self.data)

        self.config.clear()
        self.assertListEqual([], self.config.sections)

    def test_bad_identifiers(self):
        badkey = object()
        with self.assertRaises(InvalidConfigIdentifier):
            self.config.set("whoops", badkey, "foobar")
        with self.assertRaises(InvalidConfigIdentifier):
            self.config.set(badkey, "whoops", "foobar")

    def test_unicode_identifiers(self):
        test_id = u"should work"
        self.config.set("ok", test_id, self.data)
        self.assertDictEqual(self.data, self.config.get("ok", test_id))
        self.config.set(test_id, "ok", self.data)
        self.assertDictEqual(self.data, self.config.get(test_id, "ok"))

    def test_thread_safety(self):
        import Queue

        config = self.config
        data = self.data
        testcase = self
        exceptions = Queue.Queue()

        class ThreadA(threading.Thread):
            def __init__(self):
                super(ThreadA, self).__init__()
                self.config = config
                self.data = data
                self.testcase = testcase

            def run(self):
                try:
                    with self.config.lock:
                        self.config.set("barfy", "cow", self.data)
                        time.sleep(1)
                        self.testcase.assertDictEqual(
                            self.data, self.config.get("barfy", "cow"))
                except Exception as e:
                    exceptions.put(e)

        class ThreadB(threading.Thread):
            def __init__(self):
                super(ThreadB, self).__init__()
                self.config = config

            def run(self):
                try:
                    self.config.clear()
                except Exception as e:
                    exceptions.put(e)

        a = ThreadA()
        b = ThreadB()
        self.assertEqual(a.config, b.config)

        a.start()
        b.start()

        a.join()
        b.join()

        with self.assertRaises(Queue.Empty):
            raise RuntimeError("Thread safety check failed: %s" %
                               exceptions.get(block=False))

    def test_multiprocess_safety(self):
        from multiprocessing import Queue
        from Queue import Empty

        config = self.config
        data = self.data
        testcase = self
        exceptions = Queue()

        class ProcessA(multiprocessing.Process):
            def __init__(self):
                super(ProcessA, self).__init__()
                self.config = config
                self.data = data
                self.testcase = testcase

            def run(self):
                try:
                    with self.config.lock:
                        self.config.set("barfy", "cow", self.data)
                        time.sleep(1)
                        self.testcase.assertDictEqual(
                            self.data, self.config.get("barfy", "cow"))
                except Exception as e:
                    exceptions.put(e)

        class ProcessB(multiprocessing.Process):
            def __init__(self):
                super(ProcessB, self).__init__()
                self.config = config

            def run(self):
                try:
                    self.config.clear()
                except Exception as e:
                    exceptions.put(e)

        a = ProcessA()
        b = ProcessB()
        self.assertEqual(a.config, b.config)

        a.start()
        b.start()

        a.join()
        b.join()

        with self.assertRaises(Empty):
            raise RuntimeError("Multi-process safety check failed: %s" %
                               exceptions.get(block=False))

    def test_profile_managed_true(self):
        self.config.set("settings", "profile", {"managed": True})
        self.assertEqual(self.config.profile_managed, True)

    def test_profile_managed_false(self):
        self.config.set("settings", "profile", {"managed": False})
        self.assertEqual(self.config.profile_managed, False)

    def test_profile_managed_missing_false_section(self):
        self.assertEqual(self.config.profile_managed, False)

    def test_profile_managed_missing_false_ket(self):
        self.config.set("settings", "profile", {"trevor": "andy"})
        self.assertEqual(self.config.profile_managed, False)