1""" 2Unit tests for nyx.panel.graph. 3""" 4 5import datetime 6import unittest 7 8import stem.control 9 10import nyx.curses 11import nyx.panel.graph 12import test 13 14from test import require_curses 15 16try: 17 # added in python 3.3 18 from unittest.mock import patch 19except ImportError: 20 from mock import patch 21 22EXPECTED_BLANK_GRAPH = """ 23Download: 240 B 25 26 27 280 B 29 5s 10 15 30""".rstrip() 31 32EXPECTED_ACCOUNTING = """ 33Accounting (awake) Time to reset: 01:02 34 4.7 KB / 105.3 KB 2.0 KB / 9.3 KB 35""".strip() 36 37EXPECTED_GRAPH = """ 38Download: 397 KB * 40 * 413 KB ** * 42 * **** 430 B ********* 44 5s 10 15 45""".rstrip() 46 47 48class TestGraphPanel(unittest.TestCase): 49 def test_x_axis_labels(self): 50 test_inputs = { 51 0: {}, 52 7: {}, 53 10: {5: '25s'}, 54 15: {5: '25s', 10: '50'}, 55 20: {5: '25s', 10: '50', 15: '1m'}, 56 25: {5: '25s', 10: '50', 15: '1m', 20: '1.6'}, 57 45: {5: '25s', 10: '50', 15: '1m', 20: '1.6', 25: '2.0', 30: '2.5', 35: '2.9', 40: '3.3'}, 58 80: {10: '50s', 20: '1m', 30: '2.5', 40: '3.3', 50: '4.1', 60: '5.0', 70: '5.8'}, # spaced more since wide 59 } 60 61 for width, expected in test_inputs.items(): 62 self.assertEqual(expected, nyx.panel.graph._x_axis_labels(nyx.panel.graph.Interval.FIVE_SECONDS, width)) 63 64 test_inputs = { 65 nyx.panel.graph.Interval.EACH_SECOND: { 66 10: '10s', 20: '20', 30: '30', 40: '40', 50: '50', 60: '1m', 70: '1.1' 67 }, nyx.panel.graph.Interval.FIVE_SECONDS: { 68 10: '50s', 20: '1m', 30: '2.5', 40: '3.3', 50: '4.1', 60: '5.0', 70: '5.8' 69 }, nyx.panel.graph.Interval.THIRTY_SECONDS: { 70 10: '5m', 20: '10', 30: '15', 40: '20', 50: '25', 60: '30', 70: '35' 71 }, nyx.panel.graph.Interval.MINUTELY: { 72 10: '10m', 20: '20', 30: '30', 40: '40', 50: '50', 60: '1h', 70: '1.1' 73 }, nyx.panel.graph.Interval.FIFTEEN_MINUTE: { 74 10: '2h', 20: '5', 30: '7', 40: '10', 50: '12', 60: '15', 70: '17' 75 }, nyx.panel.graph.Interval.THIRTY_MINUTE: { 76 10: '5h', 20: '10', 30: '15', 40: '20', 50: '1d', 60: '1.2', 70: '1.4' 77 }, nyx.panel.graph.Interval.HOURLY: { 78 10: '10h', 20: '20', 30: '1d', 40: '1.6', 50: '2.0', 60: '2.5', 70: '2.9' 79 }, nyx.panel.graph.Interval.DAILY: { 80 10: '10d', 20: '20', 30: '30', 40: '40', 50: '50', 60: '60', 70: '70' 81 }, 82 } 83 84 for interval, expected in test_inputs.items(): 85 self.assertEqual(expected, nyx.panel.graph._x_axis_labels(interval, 80)) 86 87 def test_y_axis_labels(self): 88 data = nyx.panel.graph.ConnectionStats() 89 90 # check with both even and odd height since that determines an offset in the middle 91 92 self.assertEqual({2: '10', 4: '7', 6: '5', 9: '2', 11: '0'}, nyx.panel.graph._y_axis_labels(12, data.primary, 0, 10)) 93 self.assertEqual({2: '10', 4: '6', 6: '3', 8: '0'}, nyx.panel.graph._y_axis_labels(9, data.primary, 0, 10)) 94 95 # check where the min and max are the same 96 97 self.assertEqual({2: '0', 11: '0'}, nyx.panel.graph._y_axis_labels(12, data.primary, 0, 0)) 98 99 @require_curses 100 @patch('nyx.panel.graph.tor_controller') 101 def test_draw_subgraph_blank(self, tor_controller_mock): 102 tor_controller_mock().get_info.return_value = None 103 data = nyx.panel.graph.BandwidthStats() 104 105 rendered = test.render(nyx.panel.graph._draw_subgraph, data.primary, 0, 30, 7, nyx.panel.graph.Bounds.LOCAL_MAX, nyx.panel.graph.Interval.EACH_SECOND, nyx.curses.Color.CYAN, '*') 106 self.assertEqual(EXPECTED_BLANK_GRAPH, rendered.content) 107 108 @require_curses 109 @patch('nyx.panel.graph.tor_controller') 110 def test_draw_subgraph(self, tor_controller_mock): 111 tor_controller_mock().get_info.return_value = '5430,5430 4210,4210 5510,5510 7100,7100 2000,2000 1750,1750 1880,1880 2500,2500 3770,3770' 112 data = nyx.panel.graph.BandwidthStats() 113 114 rendered = test.render(nyx.panel.graph._draw_subgraph, data.primary, 0, 30, 7, nyx.panel.graph.Bounds.LOCAL_MAX, nyx.panel.graph.Interval.EACH_SECOND, nyx.curses.Color.CYAN, '*') 115 self.assertEqual(EXPECTED_GRAPH, rendered.content) 116 117 @require_curses 118 @patch('nyx.panel.graph.tor_controller') 119 def test_draw_accounting_stats(self, tor_controller_mock): 120 tor_controller_mock().is_alive.return_value = True 121 122 accounting_stat = stem.control.AccountingStats( 123 1410723598.276578, 124 'awake', 125 datetime.datetime(2014, 9, 14, 19, 41), 126 62, 127 4837, 102944, 107781, 128 2050, 7440, 9490, 129 ) 130 131 rendered = test.render(nyx.panel.graph._draw_accounting_stats, 0, accounting_stat) 132 self.assertEqual(EXPECTED_ACCOUNTING, rendered.content) 133 134 @require_curses 135 @patch('nyx.panel.graph.tor_controller') 136 def test_draw_accounting_stats_disconnected(self, tor_controller_mock): 137 tor_controller_mock().is_alive.return_value = False 138 rendered = test.render(nyx.panel.graph._draw_accounting_stats, 0, None) 139 self.assertEqual('Accounting: Connection Closed...', rendered.content) 140