Beispiel #1
0
    def test_doesnt_call_runner_default(self, MockRun):
        plugin = Plugin(self.domain, self.name, self.create_view)

        self.create_view.invalid.return_value = []
        self.create_view.exec_.return_value = True
        self.create_view.data.return_value = {'my': 'test', 'data': 'dict'}
        plugin.create()

        MockRun.assert_called_once_with(my='test', data='dict')
Beispiel #2
0
class TestPlugin(unittest.TestCase):
    def setUp(self):
        self.runner = MM()
        self.create_view = MM()
        self.data = {'a': 'a', 'b': 'b'}

        # set up some mock hosts
        self.host1 = MM()
        self.host1.jobs.return_value = ['host1-job1', 'host1-job2']
        self.host2 = MM()
        self.host2.jobs.return_value = ['host2-job1', 'host2-job2']
        self.hosts = [self.host1, self.host2]

        self.domain = 'rynner.swansea.ac.uk'
        self.name = 'Test Plugin'

    def instance(self, **kwargs):
        self.create_view.data.return_value = self.data
        self.create_view.invalid.return_value = []

        self.plugin = Plugin(self.domain, self.name, **kwargs)

    def test_instance(self):
        self.instance()

    @pytest.mark.xfail(
        reason='plugin.create is now non-blocking: need to refactor tests')
    def test_create_calls_setup(self):
        self.instance(runner=self.runner, create_view=self.create_view)
        self.plugin.create()
        self.runner.assert_called_once_with(self.data)

    def test_create_view_show_method_called(self):
        self.instance(create_view=self.create_view, runner=self.runner)
        self.assertFalse(self.create_view.show.called)
        self.plugin.create()
        self.assertTrue(self.create_view.show.called)

    def test_call_runner_if_no_instance(self):
        self.instance(runner=self.runner, create_view=None)
        self.plugin.create()
        self.assertFalse(self.create_view.exec_.called)
        self.assertTrue(self.runner.called)

    def test_can_add_action(self):
        some_action = lambda data: None

        self.instance()
        action = self.plugin.add_action('action label', some_action)
        self.assertIn(action, self.plugin.actions)

    def test_action_is_instance_of_action_class(self):
        some_action = lambda data: None

        self.instance()
        action = self.plugin.add_action('action label', some_action)
        actions = self.plugin.actions
        self.assertIs(type(actions[0]), RunAction)

    def test_action_created_with_pattern_parser_and_label(self):
        self.instance()

        action_function = MM()
        action_label = MM()

        action = self.plugin.add_action(action_label, action_function)
        self.assertEqual(action.label, action_label)
        self.assertEqual(action.function, action_function)

    def test_create_can_handle_empty_data(self):
        self.instance(runner=self.runner)
        self.data = {}
        self.plugin.create()

    def test_call_runner_if_create_view_valid_and_accepted(self):
        # runner is called on create when create_view is valid
        self.instance(runner=self.runner)
        self.create_view.exec_.return_value = True
        self.create_view.invalid.return_value = []
        self.plugin.create()
        self.assertTrue(self.runner.called)

    @pytest.mark.xfail(reason='plugin.create is non-blocking now')
    def test_doesnt_call_runner_if_create_view_is_invalid(self):
        # runner is not called when invalid
        self.instance(runner=self.runner, create_view=self.create_view)
        self.create_view.exec_.return_value = True
        self.create_view.invalid.return_value = ['a', 'b']
        self.plugin.create()
        self.assertTrue(self.create_view.invalid.called)
        self.assertFalse(self.runner.called)

    def test_hosts_none_by_default(self):
        self.instance()
        self.assertEqual(self.plugin.hosts, [])

    def test_doesnt_call_runner_if_exec_cancelled(self):
        # runner is not called when invalid
        self.instance(runner=self.runner, create_view=self.create_view)
        self.create_view.invalid.return_value = []
        self.create_view.exec_.return_value = False
        self.plugin.create()
        self.assertTrue(self.create_view.show.called)
        self.assertFalse(self.runner.called)

    @pytest.mark.xfail(reason='plugin.create is now non-blocking')
    @patch('rynner.plugin.Run')
    def test_doesnt_call_runner_default(self, MockRun):
        plugin = Plugin(self.domain, self.name, self.create_view)

        self.create_view.invalid.return_value = []
        self.create_view.exec_.return_value = True
        self.create_view.data.return_value = {'my': 'test', 'data': 'dict'}
        plugin.create()

        MockRun.assert_called_once_with(my='test', data='dict')

    def test_set_view_keys_stored(self):
        view_keys = MM()
        plugin = Plugin(
            self.domain, self.name, self.create_view, view_keys=view_keys)
        self.assertEqual(view_keys, plugin.view_keys)

    def test_set_view_keys_default(self):
        plugin = Plugin(self.domain, self.name, self.create_view)
        self.assertEqual(plugin.view_keys, Plugin.view_keys)

    def test_assert_default_view_keys_values(self):
        self.assertEqual(Plugin.view_keys, (
            "id",
            "name",
        ))

    def test_default_param_values(self):
        plugin = Plugin(self.domain, self.name, self.create_view)
        self.assertEqual(plugin.view_keys, ("id", "name"))

    def test_add_list_jobs(self):
        self.instance()
        ret = self.plugin.list_jobs([])
        self.assertEqual(ret, [])

    def test_add_list_jobs(self):
        self.instance()
        self.plugin.hosts = [self.host1]
        ret = self.plugin.list_jobs()
        self.assertEqual(ret, ['host1-job1', 'host1-job2'])

    def test_add_list_jobs_multi_hosts(self):
        self.instance()
        self.plugin.hosts = self.hosts
        ret = self.plugin.list_jobs()
        self.assertEqual(
            ret, ['host1-job1', 'host1-job2', 'host2-job1', 'host2-job2'])

    def test_calls_host_jobs_with_domain(self):
        self.instance()
        self.plugin.hosts = self.hosts
        self.plugin.list_jobs()
        self.host1.jobs.assert_called_once_with(self.domain)
        self.host2.jobs.assert_called_once_with(self.domain)

    def test_add_labels(self):
        labels = MM()
        plugin = Plugin(self.domain, self.name, labels=labels)
        self.assertEqual(plugin.labels, labels)

    def test_add_labels(self):
        labels = MM()
        plugin = Plugin(self.domain, self.name)
        self.assertEqual(plugin.labels, None)

    def test_build_index_view(self):
        view_class = MM()
        self.instance(build_index_view=view_class)
        self.assertEqual(self.plugin.build_index_view, view_class)

    def test_build_index_view_default(self):
        self.instance()
        self.assertEqual(self.plugin.build_index_view, None)

    def test_create_view_is_stored(self):
        create_view = MM()
        self.instance(create_view=create_view)
        self.assertEqual(self.plugin.create_view, create_view)

    def test_create_view_none_by_default(self):
        self.instance()
        self.assertEqual(self.plugin.create_view, None)

    def test_has_runs_changed_signal(self):
        self.instance()
        self.assertIsInstance(self.plugin.runs_changed, Signal)

    def test_plugin_signal_connectable(self):
        # note: signal cannot be connected to slot if QObject init not called
        a = Plugin('name', [])
        a.runs_changed.connect(lambda x: None)

    def test_plugin_set_parent(self):
        parent = QWidget()
        a = Plugin('name', [], parent=parent)
        self.assertEqual(a.parent(), parent)

    def test_none_parent_by_default(self):
        parent = QWidget()
        a = Plugin('name', [])
        self.assertEqual(a.parent(), None)

    def test_create_view_signal_connected(self):
        self.instance(create_view=self.create_view)
        self.create_view.accepted.connect.assert_called_once_with(
            self.plugin.config_accepted)
class TestPluginIntegration(qtest_helpers.QTestCase):
    def setUp(self):
        self.widgets = [
            TextField('key', 'My Label', default="My Default"),
            TextField('another_key',
                      'My Other Label',
                      default="My Other Default"),
        ]
        self.run_create_view = RunCreateView(self.widgets)
        self.runner = lambda run_manager, data: None
        self.domain = 'swansea.ac.uk'
        self.type_name = 'My Run Type'

    def instance(self):
        self.plugin = Plugin(self.domain, self.type_name, self.run_create_view,
                             self.runner)

        # find all buttons in
        view = self.plugin.create_view

        self.ok_button = qtest_helpers.find_QPushButton(view, 'ok')
        self.cancel_button = qtest_helpers.find_QPushButton(view, 'cancel')

    def test_show_config_window_for_empty_runner(self):
        '''
        show the dialog box on plugin.create, hide on click OK
        '''
        self.instance()

        self.assertNotQVisible(self.plugin.create_view)

        def call_create():
            self.assertQVisible(self.plugin.create_view)
            self.ok_button.click()
            self.assertNotQVisible(self.plugin.create_view)

        QTimer.singleShot(10, call_create)

        self.plugin.create()

    def test_dismiss_on_cancel(self):
        '''
        show the dialog box on plugin.create, hide on click cancel
        '''
        self.instance()

        def call_create():
            self.assertQVisible(self.plugin.create_view)
            self.cancel_button.click()
            self.assertNotQVisible(self.plugin.create_view)

        QTimer.singleShot(10, call_create)

        self.plugin.create()

    @pytest.mark.xfail(
        reason='do I need to wait for window to get created here?')
    def test_run_empty_runner(self):
        self.runner = MM()
        self.instance()

        qtest_helpers.button_callback(method=self.plugin.create,
                                      button=self.ok_button)

        self.runner.assert_called_once_with(self.plugin.run_manager, {
            'key': 'My Default',
            'another_key': 'My Other Default'
        })

    @pytest.mark.xfail(reason='known failure, reason no known. timing?')
    def test_throws_error_without_host(self):
        run_create_view = RunCreateView([
            TextField('Some Parameter', 'param', default='Some default value')
        ])

        connection = MM()
        connection.run_command.return_value = (0, "std out", "std err")

        # job_id is a hack to get the run id out of the runner function
        job_id = []

        def runner(run_manager, data):
            datastore = MM()
            defaults = []
            host_pattern = [('#FAKE num_nodes={}', 'nodes'),
                            ('#FAKE memory={}', 'memory')]

            pattern_parser = PatternParser(host_pattern, 'submit_cmd',
                                           defaults)

            rid = run_manager.new(nodes=10,
                                  memory=10000,
                                  host=Host(pattern_parser, connection,
                                            datastore),
                                  script='my_command')

            job_id.append(rid)

        rt = Plugin(self.domain, self.type_name, run_create_view, runner)

        button = qtest_helpers.find_QPushButton(rt.create_view, 'ok')
        qtest_helpers.button_callback(method=rt.create, button=button)

        connection.put_file_content.assert_called_once_with(
            '#FAKE num_nodes=10\n#FAKE memory=10000\nmy_command\n',
            f'{job_id[0]}/jobcard')
        connection.run_command.assert_called_once_with('submit_cmd',
                                                       pwd=f'{job_id[0]}')

    @unittest.skip('expected failure')
    def test_dialog_window_test_pattern_parser(self):
        # run_create_view can be accepted
        # - window title
        # - validation
        # - reset values
        # - multiple initialisations same widget
        # - converting to values
        assert False