Пример #1
0
 def setUp(self):
     super(SysInfoPluginRegistryTest, self).setUp()
     self.sysinfo = SysInfoPluginRegistry()
     self.sysinfo_logfile = StringIO()
     self.handler = StreamHandler(self.sysinfo_logfile)
     self.logger = getLogger("landscape-sysinfo")
     self.logger.addHandler(self.handler)
Пример #2
0
 def setUp(self):
     super(ProcessesTest, self).setUp()
     self.fake_proc = self.makeDir()
     self.processes = Processes(proc_dir=self.fake_proc)
     self.sysinfo = SysInfoPluginRegistry()
     self.sysinfo.add(self.processes)
     self.builder = ProcessDataBuilder(self.fake_proc)
Пример #3
0
class NetworkTest(TwistedTestCase, unittest.TestCase):
    def setUp(self):
        super(NetworkTest, self).setUp()
        self.result = []
        self.network = Network(lambda: self.result)
        self.sysinfo = SysInfoPluginRegistry()
        self.sysinfo.add(self.network)

    def test_run_returns_succeeded_deferred(self):
        """L{Network.run} always returns a succeeded C{Deferred}."""
        self.assertIs(None, self.successResultOf(self.network.run()))

    def test_run_adds_header(self):
        """
        A header is written to sysinfo output for each network device reported
        by L{get_active_device_info}.
        """
        self.result = [{"interface": "eth0", "ip_address": "192.168.0.50"}]
        self.network.run()
        self.assertEqual([("IP address for eth0", "192.168.0.50")],
                         self.sysinfo.get_headers())

    def test_run_without_network_devices(self):
        """
        If no network device information is available, no headers are added to
        the sysinfo output.
        """
        self.network.run()
        self.assertEqual([], self.sysinfo.get_headers())
Пример #4
0
    def setUp(self):
        super(DiskTest, self).setUp()
        self.mount_file = self.makeFile("")
        self.stat_results = {}

        self.disk = Disk(mounts_file=self.mount_file,
                         statvfs=self.stat_results.get)
        self.sysinfo = SysInfoPluginRegistry()
        self.sysinfo.add(self.disk)
Пример #5
0
class MemoryTest(FSTestCase, TwistedTestCase, unittest.TestCase):

    def setUp(self):
        super(MemoryTest, self).setUp()
        self.memory = Memory(self.makeFile(MEMINFO_SAMPLE))
        self.sysinfo = SysInfoPluginRegistry()
        self.sysinfo.add(self.memory)

    def test_run_returns_succeeded_deferred(self):
        self.assertIs(None, self.successResultOf(self.memory.run()))

    def test_run_adds_header(self):
        self.memory.run()
        self.assertEqual(self.sysinfo.get_headers(),
                         [("Memory usage", "27%"),
                          ("Swap usage", "39%")])
Пример #6
0
def run(args, reactor=None, sysinfo=None):
    """
    @param reactor: The reactor to (optionally) run the sysinfo plugins in.
    """
    try:
        setup_logging()
    except IOError as e:
        sys.exit("Unable to setup logging. %s" % e)

    if sysinfo is None:
        sysinfo = SysInfoPluginRegistry()
    config = SysInfoConfiguration()
    # landscape-sysinfo needs to work where there's no
    # /etc/landscape/client.conf See lp:1293990
    config.load(args, accept_nonexistent_default_config=True)
    for plugin in config.get_plugins():
        sysinfo.add(plugin)

    def show_output(result):
        print(
            format_sysinfo(sysinfo.get_headers(),
                           sysinfo.get_notes(),
                           sysinfo.get_footnotes(),
                           indent="  "))

    def run_sysinfo():
        return sysinfo.run().addCallback(show_output)

    if reactor is not None:
        # In case any plugins run processes or do other things that require the
        # reactor to already be started, we delay them until the reactor is
        # running.
        done = Deferred()
        reactor.callWhenRunning(
            lambda: maybeDeferred(run_sysinfo).chainDeferred(done))

        def stop_reactor(result):
            # We won't need to use callLater here once we use Twisted >8.
            # tm:3011
            reactor.callLater(0, reactor.stop)
            return result

        done.addBoth(stop_reactor)
        reactor.run()
    else:
        done = run_sysinfo()
    return done
Пример #7
0
    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)
Пример #8
0
class LandscapeLinkTest(TwistedTestCase, unittest.TestCase):

    def setUp(self):
        super(LandscapeLinkTest, self).setUp()
        self.landscape_link = LandscapeLink()
        self.sysinfo = SysInfoPluginRegistry()
        self.sysinfo.add(self.landscape_link)

    def test_run_returns_succeeded_deferred(self):
        self.assertIs(None, self.successResultOf(self.landscape_link.run()))

    def test_run_adds_footnote(self):
        self.landscape_link.run()
        self.assertEqual(
            self.sysinfo.get_footnotes(),
            ["Graph this data and manage this system at:\n"
             "    https://landscape.canonical.com/"])
class LoggedInUsersTest(FakeWhoQTest):
    def setUp(self):
        super(LoggedInUsersTest, self).setUp()
        self.logged_users = LoggedInUsers()
        self.sysinfo = SysInfoPluginRegistry()
        self.sysinfo.add(self.logged_users)

    def test_run_adds_header(self):
        self.fake_who("one two three")
        result = self.logged_users.run()

        def check_headers(result):
            self.assertEqual(self.sysinfo.get_headers(),
                             [("Users logged in", "3")])

        return result.addCallback(check_headers)

    def test_order_is_preserved_even_if_asynchronous(self):
        self.fake_who("one two three")
        self.sysinfo.add_header("Before", "1")
        result = self.logged_users.run()
        self.sysinfo.add_header("After", "2")

        def check_headers(result):
            self.assertEqual(self.sysinfo.get_headers(),
                             [("Before", "1"), ("Users logged in", "3"),
                              ("After", "2")])

        return result.addCallback(check_headers)

    def test_ignore_errors_on_command(self):
        self.fake_who("")
        who = open(self.who_path, "w")
        who.write("#!/bin/sh\necho ERROR >&2\nexit 1\n")
        who.close()
        # Nothing bad should happen if who isn't installed, or
        # if anything else happens with the command execution.
        result = self.logged_users.run()

        def check_headers(result):
            self.assertEqual(self.sysinfo.get_headers(), [])

        return result.addCallback(check_headers)
Пример #10
0
    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())
Пример #11
0
class ProcessesTest(FSTestCase, TwistedTestCase, unittest.TestCase):

    def setUp(self):
        super(ProcessesTest, self).setUp()
        self.fake_proc = self.makeDir()
        self.processes = Processes(proc_dir=self.fake_proc)
        self.sysinfo = SysInfoPluginRegistry()
        self.sysinfo.add(self.processes)
        self.builder = ProcessDataBuilder(self.fake_proc)

    def test_run_returns_succeeded_deferred(self):
        result = self.processes.run()
        self.assertTrue(isinstance(result, Deferred))
        called = []

        def callback(result):
            called.append(True)
        result.addCallback(callback)
        self.assertTrue(called)

    def test_number_of_processes(self):
        """The number of processes is added as a header."""
        for i in range(3):
            self.builder.create_data(i, self.builder.RUNNING, uid=0, gid=0,
                                     process_name="foo%d" % (i,))
        self.processes.run()
        self.assertEqual(self.sysinfo.get_headers(),
                         [("Processes", "3")])

    def test_no_zombies(self):
        self.processes.run()
        self.assertEqual(self.sysinfo.get_notes(), [])

    def test_number_of_zombies(self):
        """The number of zombies is added as a note."""
        self.builder.create_data(99, self.builder.ZOMBIE, uid=0, gid=0,
                                 process_name="ZOMBERS")
        self.processes.run()
        self.assertEqual(self.sysinfo.get_notes(),
                         ["There is 1 zombie process."])

    def test_multiple_zombies(self):
        """Stupid English, and its plurality"""
        for i in range(2):
            self.builder.create_data(i, self.builder.ZOMBIE, uid=0, gid=0,
                                     process_name="ZOMBERS%d" % (i,))
        self.processes.run()
        self.assertEqual(self.sysinfo.get_notes(),
                         ["There are 2 zombie processes."])
Пример #12
0
class TemperatureTest(ThermalZoneTest):

    def setUp(self):
        super(TemperatureTest, self).setUp()
        self.temperature = Temperature(self.thermal_zone_path)
        self.sysinfo = SysInfoPluginRegistry()
        self.sysinfo.add(self.temperature)

    def test_run_returns_succeeded_deferred(self):
        self.assertIs(None, self.successResultOf(self.temperature.run()))

    def test_run_adds_header(self):
        self.write_thermal_zone("THM0", "51000")
        self.temperature.run()
        self.assertEqual(self.sysinfo.get_headers(),
                         [("Temperature", "51.0 C")])

    def test_ignores_bad_files(self):
        self.write_thermal_zone("THM0", "")
        temperature_path = os.path.join(self.thermal_zone_path,
                                        "THM0/temp")
        file = open(temperature_path, "w")
        file.write("bad-label: 51 C")
        file.close()
        self.temperature.run()
        self.assertEqual(self.sysinfo.get_headers(), [])

    def test_ignores_unknown_formats(self):
        self.write_thermal_zone("THM0", "FOO")
        self.temperature.run()
        self.assertEqual(self.sysinfo.get_headers(), [])

    def test_picks_highest_temperature(self):
        self.write_thermal_zone("THM0", "51000")
        self.write_thermal_zone("THM1", "53000")
        self.write_thermal_zone("THM2", "52000")
        self.temperature.run()
        self.assertEqual(self.sysinfo.get_headers(),
                         [("Temperature", "53.0 C")])
Пример #13
0
 def setUp(self):
     super(LandscapeLinkTest, self).setUp()
     self.landscape_link = LandscapeLink()
     self.sysinfo = SysInfoPluginRegistry()
     self.sysinfo.add(self.landscape_link)
Пример #14
0
class SysInfoPluginRegistryTest(HelperTestCase):
    def setUp(self):
        super(SysInfoPluginRegistryTest, self).setUp()
        self.sysinfo = SysInfoPluginRegistry()
        self.sysinfo_logfile = StringIO()
        self.handler = StreamHandler(self.sysinfo_logfile)
        self.logger = getLogger("landscape-sysinfo")
        self.logger.addHandler(self.handler)

    def tearDown(self):
        super(SysInfoPluginRegistryTest, self).tearDown()
        self.logger.removeHandler(self.handler)

    def test_is_plugin_registry(self):
        self.assertTrue(isinstance(self.sysinfo, PluginRegistry))

    def test_add_and_get_headers(self):
        self.sysinfo.add_header("Memory usage", "65%")
        self.sysinfo.add_header("Swap usage", "None")
        self.assertEqual(self.sysinfo.get_headers(), [("Memory usage", "65%"),
                                                      ("Swap usage", "None")])
        self.assertEqual(self.sysinfo.get_notes(), [])
        self.assertEqual(self.sysinfo.get_footnotes(), [])

    def test_add_same_header_twice(self):
        self.sysinfo.add_header("Header1", "Value1")
        self.sysinfo.add_header("Header2", "Value2")
        self.sysinfo.add_header("Header3", "Value3")
        self.sysinfo.add_header("Header2", "Value4")
        self.assertEqual(self.sysinfo.get_headers(), [("Header1", "Value1"),
                                                      ("Header2", "Value4"),
                                                      ("Header3", "Value3")])

    def test_add_header_with_none_value(self):
        self.sysinfo.add_header("Header1", "Value1")
        self.sysinfo.add_header("Header2", None)
        self.sysinfo.add_header("Header3", "Value3")
        self.assertEqual(self.sysinfo.get_headers(), [("Header1", "Value1"),
                                                      ("Header3", "Value3")])
        self.sysinfo.add_header("Header2", "Value2")
        self.assertEqual(self.sysinfo.get_headers(), [("Header1", "Value1"),
                                                      ("Header2", "Value2"),
                                                      ("Header3", "Value3")])

    def test_add_and_get_notes(self):
        self.sysinfo.add_note("Your laptop is burning!")
        self.sysinfo.add_note("Oh, your house too, btw.")
        self.assertEqual(
            self.sysinfo.get_notes(),
            ["Your laptop is burning!", "Oh, your house too, btw."])
        self.assertEqual(self.sysinfo.get_headers(), [])
        self.assertEqual(self.sysinfo.get_footnotes(), [])

    def test_add_and_get_footnotes(self):
        self.sysinfo.add_footnote("Graphs available at http://graph")
        self.sysinfo.add_footnote("Go! Go!")
        self.assertEqual(self.sysinfo.get_footnotes(),
                         ["Graphs available at http://graph", "Go! Go!"])
        self.assertEqual(self.sysinfo.get_headers(), [])
        self.assertEqual(self.sysinfo.get_notes(), [])

    def test_run(self):
        class Plugin(object):
            def __init__(self, deferred):
                self._deferred = deferred

            def register(self, registry):
                pass

            def run(self):
                return self._deferred

        plugin_deferred1 = Deferred()
        plugin_deferred2 = Deferred()

        plugin1 = Plugin(plugin_deferred1)
        plugin2 = Plugin(plugin_deferred2)

        self.sysinfo.add(plugin1)
        self.sysinfo.add(plugin2)

        def check_result(result):
            self.assertEqual(result, [123, 456])

        deferred = self.sysinfo.run()
        deferred.addBoth(check_result)

        self.assertEqual(deferred.called, False)
        plugin_deferred1.callback(123)
        self.assertEqual(deferred.called, False)
        plugin_deferred2.callback(456)
        self.assertEqual(deferred.called, True)

    plugin_exception_message = (
        "There were exceptions while processing one or more plugins. "
        "See %s/sysinfo.log for more information.")

    def test_plugins_run_after_synchronous_error(self):
        """
        Even when a plugin raises a synchronous error, other plugins will
        continue to be run.
        """
        self.log_helper.ignore_errors(ZeroDivisionError)
        plugins_what_run = []

        class BadPlugin(object):
            def register(self, registry):
                pass

            def run(self):
                plugins_what_run.append(self)
                1 / 0

        class GoodPlugin(object):
            def register(self, registry):
                pass

            def run(self):
                plugins_what_run.append(self)
                return succeed(None)

        plugin1 = BadPlugin()
        plugin2 = GoodPlugin()
        self.sysinfo.add(plugin1)
        self.sysinfo.add(plugin2)
        self.sysinfo.run()
        self.assertEqual(plugins_what_run, [plugin1, plugin2])
        log = self.sysinfo_logfile.getvalue()
        message = "BadPlugin plugin raised an exception."
        self.assertIn(message, log)
        self.assertIn("1 / 0", log)
        self.assertIn("ZeroDivisionError", log)

        path = os.path.expanduser("~/.landscape")
        self.assertEqual(self.sysinfo.get_notes(),
                         [self.plugin_exception_message % path])

    def test_asynchronous_errors_logged(self):
        self.log_helper.ignore_errors(ZeroDivisionError)

        class BadPlugin(object):
            def register(self, registry):
                pass

            def run(self):
                return fail(ZeroDivisionError("yay"))

        plugin = BadPlugin()
        self.sysinfo.add(plugin)
        self.sysinfo.run()
        log = self.sysinfo_logfile.getvalue()
        message = "BadPlugin plugin raised an exception."
        self.assertIn(message, log)
        self.assertIn("ZeroDivisionError: yay", log)
        path = os.path.expanduser("~/.landscape")
        self.assertEqual(self.sysinfo.get_notes(),
                         [self.plugin_exception_message % path])

    def test_multiple_exceptions_get_one_note(self):
        self.log_helper.ignore_errors(ZeroDivisionError)

        class RegularBadPlugin(object):
            def register(self, registry):
                pass

            def run(self):
                1 / 0

        class AsyncBadPlugin(object):
            def register(self, registry):
                pass

            def run(self):
                return fail(ZeroDivisionError("Hi"))

        plugin1 = RegularBadPlugin()
        plugin2 = AsyncBadPlugin()
        self.sysinfo.add(plugin1)
        self.sysinfo.add(plugin2)
        self.sysinfo.run()

        path = os.path.expanduser("~/.landscape")
        self.assertEqual(self.sysinfo.get_notes(),
                         [self.plugin_exception_message % path])

    @mock.patch("os.getuid", return_value=0)
    def test_exception_running_as_privileged_user(self, uid_mock):
        """
        If a Plugin fails while running and the sysinfo binary is running with
        a uid of 0, Landscape sysinfo should write to the system logs
        directory.
        """
        class AsyncBadPlugin(object):
            def register(self, registry):
                pass

            def run(self):
                return fail(ZeroDivisionError("Hi"))

        self.log_helper.ignore_errors(ZeroDivisionError)

        plugin = AsyncBadPlugin()
        self.sysinfo.add(plugin)
        self.sysinfo.run()
        uid_mock.assert_called_with()

        path = "/var/log/landscape"
        self.assertEqual(self.sysinfo.get_notes(),
                         [self.plugin_exception_message % path])
Пример #15
0
 def setUp(self):
     super(MemoryTest, self).setUp()
     self.memory = Memory(self.makeFile(MEMINFO_SAMPLE))
     self.sysinfo = SysInfoPluginRegistry()
     self.sysinfo.add(self.memory)
Пример #16
0
class DiskTest(FSTestCase, unittest.TestCase):
    def setUp(self):
        super(DiskTest, self).setUp()
        self.mount_file = self.makeFile("")
        self.stat_results = {}

        self.disk = Disk(mounts_file=self.mount_file,
                         statvfs=self.stat_results.get)
        self.sysinfo = SysInfoPluginRegistry()
        self.sysinfo.add(self.disk)

    def add_mount(self,
                  point,
                  block_size=4096,
                  capacity=1000,
                  unused=1000,
                  fs="ext3",
                  device=None):
        if device is None:
            device = "/dev/" + point.replace("/", "_")
        self.stat_results[point] = os.statvfs_result(
            (block_size, 0, capacity, unused, 0, 0, 0, 0, 0, 0))
        f = open(self.mount_file, "a")
        f.write("/dev/%s %s %s rw 0 0\n" % (device, point, fs))
        f.close()

    def test_run_returns_succeeded_deferred(self):
        self.add_mount("/")
        result = self.disk.run()
        self.assertTrue(isinstance(result, Deferred))
        called = []

        def callback(result):
            called.append(True)

        result.addCallback(callback)
        self.assertTrue(called)

    def test_everything_is_cool(self):
        self.add_mount("/")
        self.disk.run()
        self.assertEqual(self.sysinfo.get_notes(), [])

    def test_zero_total_space(self):
        """
        When the total space for a mount is 0, the plugin shouldn't flip out
        and kill everybody.

        This is a regression test for a ZeroDivisionError!
        """
        self.add_mount("/sys", capacity=0, unused=0)
        self.add_mount("/")
        self.disk.run()
        self.assertEqual(self.sysinfo.get_notes(), [])

    def test_zero_total_space_for_home(self):
        """
        When the total space for /home is 0, we'll fall back to /.
        """
        self.add_mount("/home", capacity=0, unused=0)
        self.add_mount("/", capacity=1000, unused=1000)
        self.disk.run()
        self.assertEqual(self.sysinfo.get_headers(),
                         [("Usage of /", "0.0% of 3MB")])

    def test_zero_total_space_for_home_and_root(self):
        """
        In a very strange situation, when both /home and / have a capacity of
        0, we'll show 'unknown' for the usage of /.
        """
        self.add_mount("/home", capacity=0, unused=0)
        self.add_mount("/", capacity=0, unused=0)
        self.disk.run()
        self.assertEqual(self.sysinfo.get_headers(),
                         [("Usage of /", "unknown")])

    def test_over_85_percent(self):
        """
        When a filesystem is using more than 85% capacity, a note will be
        displayed.
        """
        self.add_mount("/", capacity=1000000, unused=150000)
        self.disk.run()
        self.assertEqual(self.sysinfo.get_notes(),
                         ["/ is using 85.0% of 3.81GB"])

    def test_under_85_percent(self):
        """No note is displayed for a filesystem using less than 85% capacity.
        """
        self.add_mount("/", block_size=1024, capacity=1000000, unused=151000)
        self.disk.run()
        self.assertEqual(self.sysinfo.get_notes(), [])

    def test_multiple_notes(self):
        """
        A note will be displayed for each filesystem using 85% or more
        capacity.
        """
        self.add_mount("/", block_size=1024, capacity=1000000, unused=150000)
        self.add_mount("/use",
                       block_size=2048,
                       capacity=2000000,
                       unused=200000)
        self.add_mount("/emp",
                       block_size=4096,
                       capacity=3000000,
                       unused=460000)
        self.disk.run()
        self.assertEqual(
            self.sysinfo.get_notes(),
            ["/ is using 85.0% of 976MB", "/use is using 90.0% of 3.81GB"])

    def test_format_megabytes(self):
        self.assertEqual(format_megabytes(100), "100MB")
        self.assertEqual(format_megabytes(1023), "1023MB")
        self.assertEqual(format_megabytes(1024), "1.00GB")
        self.assertEqual(format_megabytes(1024 * 1024 - 1), "1024.00GB")
        self.assertEqual(format_megabytes(1024 * 1024), "1.00TB")

    def test_header(self):
        """
        A header is printed with usage for the 'primary' filesystem, where
        'primary' means 'filesystem that has /home on it'.
        """
        self.add_mount("/")
        self.add_mount("/home", capacity=1024, unused=512)
        self.disk.run()
        self.assertEqual(self.sysinfo.get_headers(),
                         [("Usage of /home", "50.0% of 4MB")])

    def test_header_shows_actual_filesystem(self):
        """
        If /home isn't on its own filesystem, the header will show whatever
        filesystem it's a part of.
        """
        self.add_mount("/", capacity=1024, unused=512)
        self.disk.run()
        self.assertEqual(self.sysinfo.get_headers(),
                         [("Usage of /", "50.0% of 4MB")])

    def test_ignore_boring_filesystem_types(self):
        """
        Optical drives (those with filesystems of udf or iso9660) should be
        ignored.

        Also, gvfs mounts should be ignored, because they actually reflect the
        size of /.
        """
        self.add_mount("/", capacity=1000, unused=1000, fs="ext3")
        self.add_mount("/media/dvdrom", capacity=1000, unused=0, fs="udf")
        self.add_mount("/media/cdrom", capacity=1000, unused=0, fs="iso9660")
        self.add_mount("/home/radix/.gvfs",
                       capacity=1000,
                       unused=0,
                       fs="fuse.gvfs-fuse-daemon")
        self.add_mount("/mnt/livecd", capacity=1000, unused=0, fs="squashfs")
        self.add_mount("/home/mg/.Private",
                       capacity=1000,
                       unused=0,
                       fs="ecryptfs")
        self.disk.run()
        self.assertEqual(self.sysinfo.get_notes(), [])

    def test_no_duplicate_roots(self):
        self.add_mount("/", capacity=0, unused=0, fs="ext4")
        self.add_mount("/", capacity=1000, unused=1, fs="ext3")
        self.disk.run()
        self.assertEqual(self.sysinfo.get_notes(),
                         ["/ is using 100.0% of 3MB"])

    def test_no_duplicate_devices(self):
        self.add_mount("/", capacity=1000, unused=1, device="/dev/horgle")
        self.add_mount("/dev/.static/dev",
                       capacity=1000,
                       unused=1,
                       device="/dev/horgle")
        self.disk.run()
        self.assertEqual(self.sysinfo.get_notes(),
                         ["/ is using 100.0% of 3MB"])

    def test_shorter_mount_point_in_case_of_duplicate_devices(self):
        self.add_mount("/dev/.static/dev",
                       capacity=1000,
                       unused=1,
                       device="/dev/horgle")
        self.add_mount("/", capacity=1000, unused=1, device="/dev/horgle")
        self.disk.run()
        self.assertEqual(self.sysinfo.get_notes(),
                         ["/ is using 100.0% of 3MB"])

    def test_shorter_not_lexical(self):
        """
        This is a test for a fix for a regression, because I accidentally took
        the lexically "smallest" mount point instead of the shortest one.
        """
        self.add_mount("/")
        self.add_mount("/abc", capacity=1000, unused=1, device="/dev/horgle")
        self.add_mount("/b", capacity=1000, unused=1, device="/dev/horgle")
        self.disk.run()
        self.assertEqual(self.sysinfo.get_notes(),
                         ["/b is using 100.0% of 3MB"])

    def test_duplicate_device_and_duplicate_mountpoint_horribleness(self):
        """
        Consider the following:

        rootfs / rootfs rw 0 0
        /dev/disk/by-uuid/c4144... / ext3 rw,... 0 0
        /dev/disk/by-uuid/c4144... /dev/.static/dev ext3 rw,... 0 0

        (taken from an actual /proc/mounts in Hardy)

        "/", the mount point, is duplicate-mounted *and* (one of) the devices
        mounted to "/" is also duplicate-mounted.  Only "/" should be warned
        about in this case.
        """
        self.add_mount("/", capacity=0, unused=0, device="rootfs")
        self.add_mount("/", capacity=1000, unused=1, device="/dev/horgle")
        self.add_mount("/dev/.static/dev",
                       capacity=1000,
                       unused=1,
                       device="/dev/horgle")
        self.disk.run()
        self.assertEqual(self.sysinfo.get_notes(),
                         ["/ is using 100.0% of 3MB"])

    def test_ignore_filesystems(self):
        """
        Network filesystems like nfs are ignored, because they can stall
        randomly in stat.
        """
        self.add_mount("/", capacity=1000, unused=1000, fs="ext3")
        self.add_mount("/mnt/disk1", capacity=1000, unused=0, fs="nfs")
        self.disk.run()
        self.assertEqual(self.sysinfo.get_notes(), [])

    def test_nfs_as_root(self):
        """
        If / is not a whitelist filesystem, we don't report the usage of /home.
        """
        self.add_mount("/", capacity=1000, unused=1000, fs="nfs")
        self.disk.run()
        self.assertEqual(self.sysinfo.get_notes(), [])
        self.assertEqual(self.sysinfo.get_headers(),
                         [("Usage of /home", "unknown")])

    def test_nfs_as_root_but_not_home(self):
        """
        If / is not a whitelist filesystem, but that /home is with a weird stat
        value, we don't report the usage of /home.
        """
        self.add_mount("/", capacity=1000, unused=1000, fs="nfs")
        self.add_mount("/home", capacity=0, unused=0, fs="ext3")
        self.disk.run()
        self.assertEqual(self.sysinfo.get_notes(), [])
        self.assertEqual(self.sysinfo.get_headers(),
                         [("Usage of /home", "unknown")])
Пример #17
0
 def setUp(self):
     super(TemperatureTest, self).setUp()
     self.temperature = Temperature(self.thermal_zone_path)
     self.sysinfo = SysInfoPluginRegistry()
     self.sysinfo.add(self.temperature)
 def setUp(self):
     super(LoggedInUsersTest, self).setUp()
     self.logged_users = LoggedInUsers()
     self.sysinfo = SysInfoPluginRegistry()
     self.sysinfo.add(self.logged_users)
Пример #19
0
 def setUp(self):
     super(NetworkTest, self).setUp()
     self.result = []
     self.network = Network(lambda: self.result)
     self.sysinfo = SysInfoPluginRegistry()
     self.sysinfo.add(self.network)
Пример #20
0
class NetworkTest(TwistedTestCase, unittest.TestCase):
    def setUp(self):
        super(NetworkTest, self).setUp()
        self.result = []
        self.network = Network(lambda: self.result)
        self.sysinfo = SysInfoPluginRegistry()
        self.sysinfo.add(self.network)

    def test_run_returns_succeeded_deferred(self):
        """L{Network.run} always returns a succeeded C{Deferred}."""
        self.assertIs(None, self.successResultOf(self.network.run()))

    def test_run_single_interface_ipv4_address(self):
        """
        A header is written to sysinfo output for each network device reported
        by L{get_active_device_info}.
        """
        self.result = [{
            "interface": "eth0",
            "ip_address": "IGNORED",
            "ip_addresses": {
                AF_INET: [{
                    "addr": "192.168.0.50"
                }]
            }
        }]

        self.network.run()
        self.assertEqual([("IPv4 address for eth0", "192.168.0.50")],
                         self.sysinfo.get_headers())

    def test_run_single_interface_ipv6_address(self):
        self.result = [{
            "interface": "eth0",
            "ip_address": "IGNORED",
            "ip_addresses": {
                AF_INET6: [{
                    "addr": "2001::1"
                }]
            }
        }]

        self.network.run()
        self.assertEqual([("IPv6 address for eth0", "2001::1")],
                         self.sysinfo.get_headers())

    def test_run_multiple_interface_multiple_addresses(self):
        """
        A header is written to sysinfo output for each network device reported
        by L{get_active_device_info}.
        """
        self.result = [{
            "interface": "eth0",
            "ip_addresses": {
                AF_INET: [{
                    "addr": "192.168.0.50"
                }, {
                    "addr": "192.168.1.50"
                }]
            },
        }, {
            "interface": "eth1",
            "ip_addresses": {
                AF_INET: [{
                    "addr": "192.168.2.50"
                }, {
                    "addr": "192.168.3.50"
                }],
                AF_INET6: [{
                    "addr": "2001::1"
                }, {
                    "addr": "2002::2"
                }]
            },
        }, {
            "interface": "eth2",
            "ip_addresses": {
                AF_INET6: [{
                    "addr": "2003::3"
                }, {
                    "addr": "2004::4"
                }]
            },
        }]

        self.network.run()
        self.assertEqual([("IPv4 address for eth0", "192.168.0.50"),
                          ("IPv4 address for eth0", "192.168.1.50"),
                          ("IPv4 address for eth1", "192.168.2.50"),
                          ("IPv4 address for eth1", "192.168.3.50"),
                          ("IPv6 address for eth1", "2001::1"),
                          ("IPv6 address for eth1", "2002::2"),
                          ("IPv6 address for eth2", "2003::3"),
                          ("IPv6 address for eth2", "2004::4")],
                         self.sysinfo.get_headers())

    def test_run_without_network_devices(self):
        """
        If no network device information is available, no headers are added to
        the sysinfo output.
        """
        self.network.run()
        self.assertEqual([], self.sysinfo.get_headers())
Пример #21
0
                                  maxBytes=500 * 1024, backupCount=1)
    logger.addHandler(handler)
    handler.setFormatter(Formatter("%(asctime)s %(levelname)-8s %(message)s"))


def run(args, reactor=None, sysinfo=None):
    """
    @param reactor: The reactor to (optionally) run the sysinfo plugins in.
    """
    try:
        setup_logging()
    except IOError, e:
        sys.exit("Unable to setup logging. %s" % e)

    if sysinfo is None:
        sysinfo = SysInfoPluginRegistry()
    config = SysInfoConfiguration()
    # landscape-sysinfo needs to work where there's no
    # /etc/landscape/client.conf See lp:1293990
    config.load(args, accept_nonexistent_default_config=True)
    for plugin in config.get_plugins():
        sysinfo.add(plugin)

    def show_output(result):
        print format_sysinfo(sysinfo.get_headers(), sysinfo.get_notes(),
                             sysinfo.get_footnotes(), indent="  ")

    def run_sysinfo():
        return sysinfo.run().addCallback(show_output)

    if reactor is not None: