tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_resource_monitor.py (5348B)


      1 # This Source Code Form is subject to the terms of the Mozilla Public
      2 # License, v. 2.0. If a copy of the MPL was not distributed with this
      3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
      4 
      5 import multiprocessing
      6 import time
      7 import unittest
      8 
      9 import mozunit
     10 
     11 try:
     12    import psutil
     13 except ImportError:
     14    psutil = None
     15 
     16 from mozsystemmonitor.resourcemonitor import SystemResourceMonitor, SystemResourceUsage
     17 
     18 
     19 @unittest.skipIf(psutil is None, "Resource monitor requires psutil.")
     20 class TestResourceMonitor(unittest.TestCase):
     21    def test_basic(self):
     22        monitor = SystemResourceMonitor(poll_interval=0.5)
     23 
     24        monitor.start()
     25        time.sleep(3)
     26 
     27        monitor.stop()
     28 
     29        data = list(monitor.range_usage())
     30        self.assertGreater(len(data), 3)
     31 
     32        self.assertIsInstance(data[0], SystemResourceUsage)
     33 
     34    def test_empty(self):
     35        monitor = SystemResourceMonitor(poll_interval=2.0)
     36        monitor.start()
     37        monitor.stop()
     38 
     39        data = list(monitor.range_usage())
     40        self.assertEqual(len(data), 0)
     41 
     42    def test_phases(self):
     43        monitor = SystemResourceMonitor(poll_interval=0.25)
     44 
     45        monitor.start()
     46        time.sleep(1)
     47 
     48        with monitor.phase("phase1"):
     49            time.sleep(1)
     50 
     51            with monitor.phase("phase2"):
     52                time.sleep(1)
     53 
     54        monitor.stop()
     55 
     56        self.assertEqual(len(monitor.phases), 2)
     57        self.assertEqual(["phase2", "phase1"], list(monitor.phases.keys()))
     58 
     59        all = list(monitor.range_usage())
     60        data1 = list(monitor.phase_usage("phase1"))
     61        data2 = list(monitor.phase_usage("phase2"))
     62 
     63        self.assertGreater(len(all), len(data1))
     64        self.assertGreater(len(data1), len(data2))
     65 
     66        # This could fail if time.monotonic() takes more than 0.1s. It really
     67        # shouldn't.
     68        self.assertAlmostEqual(data1[-1].end, data2[-1].end, delta=0.25)
     69 
     70    def test_no_data(self):
     71        monitor = SystemResourceMonitor()
     72 
     73        data = list(monitor.range_usage())
     74        self.assertEqual(len(data), 0)
     75 
     76    def test_events(self):
     77        monitor = SystemResourceMonitor(poll_interval=0.25)
     78 
     79        monitor.start()
     80        time.sleep(0.5)
     81 
     82        t0 = time.monotonic()
     83        monitor.record_event("t0")
     84        time.sleep(2)
     85 
     86        monitor.record_event("t1")
     87        time.sleep(0.5)
     88        monitor.stop()
     89 
     90        events = monitor.events
     91        self.assertEqual(len(events), 2)
     92 
     93        event = events[0]
     94 
     95        self.assertEqual(event[1], "t0")
     96        self.assertAlmostEqual(event[0], t0, delta=0.25)
     97 
     98        data = list(monitor.between_events_usage("t0", "t1"))
     99        self.assertGreater(len(data), 0)
    100 
    101    def test_aggregate_cpu(self):
    102        monitor = SystemResourceMonitor(poll_interval=0.25)
    103 
    104        monitor.start()
    105        time.sleep(1)
    106        monitor.stop()
    107 
    108        values = monitor.aggregate_cpu_percent()
    109        self.assertIsInstance(values, list)
    110        self.assertEqual(len(values), multiprocessing.cpu_count())
    111        for v in values:
    112            self.assertIsInstance(v, float)
    113 
    114        value = monitor.aggregate_cpu_percent(per_cpu=False)
    115        self.assertIsInstance(value, float)
    116 
    117        values = monitor.aggregate_cpu_times()
    118        self.assertIsInstance(values, list)
    119        self.assertGreater(len(values), 0)
    120        self.assertTrue(hasattr(values[0], "user"))
    121 
    122        t = type(values[0])
    123 
    124        value = monitor.aggregate_cpu_times(per_cpu=False)
    125        self.assertIsInstance(value, t)
    126 
    127    def test_aggregate_io(self):
    128        monitor = SystemResourceMonitor(poll_interval=0.25)
    129 
    130        # There's really no easy way to ensure I/O occurs. For all we know
    131        # reads and writes will all be serviced by the page cache.
    132        monitor.start()
    133        time.sleep(1.0)
    134        monitor.stop()
    135 
    136        values = monitor.aggregate_io()
    137        self.assertTrue(hasattr(values, "read_count"))
    138 
    139    def test_memory(self):
    140        monitor = SystemResourceMonitor(poll_interval=0.25)
    141 
    142        monitor.start()
    143        time.sleep(1.0)
    144        monitor.stop()
    145 
    146        v = monitor.min_memory_available()
    147        self.assertIsInstance(v, int)
    148 
    149        v = monitor.max_memory_percent()
    150        self.assertIsInstance(v, float)
    151 
    152    def test_as_profile(self):
    153        monitor = SystemResourceMonitor(poll_interval=0.25)
    154 
    155        monitor.start()
    156        time.sleep(0.1)
    157        monitor.begin_phase("phase1")
    158        monitor.record_event("foo")
    159        time.sleep(0.1)
    160        monitor.begin_phase("phase2")
    161        monitor.record_event("bar")
    162        time.sleep(0.2)
    163        monitor.finish_phase("phase1")
    164        time.sleep(0.2)
    165        monitor.finish_phase("phase2")
    166        time.sleep(0.4)
    167        monitor.stop()
    168 
    169        d = monitor.as_profile()
    170 
    171        self.assertEqual(len(d["threads"]), 1)
    172        self.assertIn("markers", d["threads"][0])
    173        self.assertIn("data", d["threads"][0]["markers"])
    174        markers = d["threads"][0]["markers"]["data"]
    175        self.assertTrue(
    176            any(m["type"] == "Phase" and m["phase"] == "phase1" for m in markers)
    177        )
    178        self.assertTrue(
    179            any(m["type"] == "Phase" and m["phase"] == "phase2" for m in markers)
    180        )
    181        self.assertIn({"type": "Text", "text": "foo"}, markers)
    182        self.assertIn({"type": "Text", "text": "bar"}, markers)
    183 
    184 
    185 if __name__ == "__main__":
    186    mozunit.main()