def test_format_sysinfo_output_is_printed(self): with mock.patch("landscape.sysinfo.deployment.format_sysinfo", return_value="Hello there!") as format_sysinfo: run(["--sysinfo-plugins", "TestPlugin"]) self.assertTrue(format_sysinfo.called) self.assertEqual(self.stdout.getvalue(), "Hello there!\n")
def test_registry_runs_plugin_and_gets_correct_information(self): run(["--sysinfo-plugins", "TestPlugin"]) from landscape.sysinfo.testplugin import current_instance self.assertEqual(current_instance.has_run, True) sysinfo = current_instance.sysinfo self.assertEqual(sysinfo.get_headers(), [("Test header", "Test value")]) self.assertEqual(sysinfo.get_notes(), ["Test note"]) self.assertEqual(sysinfo.get_footnotes(), ["Test footnote"])
def test_default_arguments_load_default_plugins(self): result = run([]) def check_result(result): self.assertIn("System load", self.stdout.getvalue()) self.assertNotIn("Test note", self.stdout.getvalue()) return result.addCallback(check_result)
def test_stop_scheduled_in_callback(self): """ Because of tm:3011, reactor.stop() must be called in a scheduled call. """ reactor = FakeReactor() d = run(["--sysinfo-plugins", "TestPlugin"], reactor=reactor) for x in reactor.queued_calls: x() self.assertEqual(reactor.scheduled_calls, [(0, reactor.stop, (), {})]) return d
def test_missing_config_file(self): """The process doesn't fail if there is no config file.""" # Existing revert in tearDown will handle undoing this SysInfoConfiguration.default_config_filenames = [] result = run([]) def check_result(result): self.assertIn("System load", self.stdout.getvalue()) return result.addCallback(check_result)
def test_output_is_only_displayed_once_deferred_fires(self): deferred = Deferred() # We mock the sysinfo.run() to return a Deferred but still # run the actual sysinfo.run() to gather the results from all # the plugins. We cannot easily combine return_value and # side_effect because side_effect operates on the return_value, # thus firing the callback and writing sysinfo out to stdout. sysinfo = SysInfoPluginRegistry() original_sysinfo_run = sysinfo.run def wrapped_sysinfo_run(*args, **kwargs): original_sysinfo_run(*args, **kwargs) return deferred sysinfo.run = mock.Mock(side_effect=wrapped_sysinfo_run) run(["--sysinfo-plugins", "TestPlugin"], sysinfo=sysinfo) sysinfo.run.assert_called_once_with() self.assertNotIn("Test note", self.stdout.getvalue()) deferred.callback(None) self.assertIn("Test note", self.stdout.getvalue())
def test_plugins_called_after_reactor_starts(self): """ Plugins are invoked after the reactor has started, so that they can spawn processes without concern for race conditions. """ reactor = FakeReactor() d = run(["--sysinfo-plugins", "TestPlugin"], reactor=reactor) self.assertEqual(self.stdout.getvalue(), "") self.assertTrue(reactor.running) for x in reactor.queued_calls: x() self.assertEqual( self.stdout.getvalue(), " Test header: Test value\n\n => Test note\n\n Test footnote\n") return d
def test_stop_reactor_even_when_sync_exception_from_sysinfo_run(self): """ Even when there's a synchronous exception from run_sysinfo, the reactor should be stopped. """ self.log_helper.ignore_errors(ZeroDivisionError) reactor = FakeReactor() sysinfo = SysInfoPluginRegistry() sysinfo.run = lambda: 1 / 0 d = run(["--sysinfo-plugins", "TestPlugin"], reactor=reactor, sysinfo=sysinfo) for x in reactor.queued_calls: x() self.assertEqual(reactor.scheduled_calls, [(0, reactor.stop, (), {})]) return self.assertFailure(d, ZeroDivisionError)
def test_run_sets_up_logging(self): with mock.patch("landscape.sysinfo.deployment" ".setup_logging") as setup_logging_mock: run(["--sysinfo-plugins", "TestPlugin"]) setup_logging_mock.assert_called_once_with()
def test_format_sysinfo_gets_correct_information(self, format_sysinfo): run(["--sysinfo-plugins", "TestPlugin"]) format_sysinfo.assert_called_once_with([("Test header", "Test value")], ["Test note"], ["Test footnote"], indent=" ")