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')
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