Test Failed
Push — master ( aea994...69b639 )
by Nicolas
03:44 queued 10s
created

unitest   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 395
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 262
dl 0
loc 395
rs 8.96
c 0
b 0
f 0
wmc 43

27 Methods

Rating   Name   Duplication   Size   Complexity  
A TestGlances.test_004_load() 0 12 2
A TestGlances.test_015_subsample() 0 11 2
A TestGlances.test_012_ip() 0 6 1
A TestGlances.test_000_update() 0 19 3
A TestGlances.test_010_processes() 0 11 1
A TestGlances.test_009_fs() 0 7 1
A TestGlances.test_002_system() 0 9 2
A TestGlances.test_008_diskio() 0 6 1
A TestGlances.test_013_gpu() 0 7 1
A TestGlances.test_014_sorted_stats() 0 27 2
A TestGlances.setUp() 0 3 1
A TestGlances.test_013_irq() 0 7 1
A TestGlances.test_007_network() 0 6 1
A TestGlances.test_003_cpu() 0 12 2
A TestGlances.test_006_swap() 0 11 2
A TestGlances.test_011_folders() 0 7 1
A TestGlances.test_001_plugins() 0 7 2
A TestGlances.test_005_mem() 0 11 2
A TestGlances.test_097_attribute() 0 22 1
A TestGlances.test_016_hddsmart() 0 22 4
A TestGlances.test_099_output_bars_must_be_between_0_and_100_percent() 0 20 1
A TestGlances.test_095_methods() 0 9 3
A TestGlances.test_094_thresholds() 0 16 1
A TestGlances.test_098_history() 0 17 1
A TestGlances.test_096_views() 0 9 2
A TestGlances.test_100_secure() 0 6 1
A TestGlances.test_999_the_end() 0 5 1

How to fix   Complexity   

Complexity

Complex classes like unitest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
#
4
# Glances - An eye on your system
5
#
6
# Copyright (C) 2019 Nicolargo <[email protected]>
7
#
8
# Glances is free software; you can redistribute it and/or modify
9
# it under the terms of the GNU Lesser General Public License as published by
10
# the Free Software Foundation, either version 3 of the License, or
11
# (at your option) any later version.
12
#
13
# Glances is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
# GNU Lesser General Public License for more details.
17
#
18
# You should have received a copy of the GNU Lesser General Public License
19
# along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21
"""Glances unitary tests suite."""
22
23
import time
24
import unittest
25
26
from glances.main import GlancesMain
27
from glances.stats import GlancesStats
28
from glances import __version__
29
from glances.globals import WINDOWS, LINUX
30
from glances.outputs.glances_bars import Bar
31
from glances.thresholds import GlancesThresholdOk
32
from glances.thresholds import GlancesThresholdCareful
33
from glances.thresholds import GlancesThresholdWarning
34
from glances.thresholds import GlancesThresholdCritical
35
from glances.thresholds import GlancesThresholds
36
from glances.plugins.glances_plugin import GlancesPlugin
37
from glances.compat import subsample, range
38
from glances.secure import secure_popen
39
40
# Global variables
41
# =================
42
43
# Init Glances core
44
core = GlancesMain()
45
46
# Init Glances stats
47
stats = GlancesStats(config=core.get_config(),
48
                     args=core.get_args())
49
50
# Unitest class
51
# ==============
52
print('Unitary tests for Glances %s' % __version__)
53
54
55
class TestGlances(unittest.TestCase):
56
    """Test Glances class."""
57
58
    def setUp(self):
59
        """The function is called *every time* before test_*."""
60
        print('\n' + '=' * 78)
61
62
    def test_000_update(self):
63
        """Update stats (mandatory step for all the stats).
64
65
        The update is made twice (for rate computation).
66
        """
67
        print('INFO: [TEST_000] Test the stats update function')
68
        try:
69
            stats.update()
70
        except Exception as e:
71
            print('ERROR: Stats update failed: %s' % e)
72
            self.assertTrue(False)
73
        time.sleep(1)
74
        try:
75
            stats.update()
76
        except Exception as e:
77
            print('ERROR: Stats update failed: %s' % e)
78
            self.assertTrue(False)
79
80
        self.assertTrue(True)
81
82
    def test_001_plugins(self):
83
        """Check mandatory plugins."""
84
        plugins_to_check = ['system', 'cpu', 'load', 'mem', 'memswap', 'network', 'diskio', 'fs']
85
        print('INFO: [TEST_001] Check the mandatory plugins list: %s' % ', '.join(plugins_to_check))
86
        plugins_list = stats.getPluginsList()
87
        for plugin in plugins_to_check:
88
            self.assertTrue(plugin in plugins_list)
89
90
    def test_002_system(self):
91
        """Check SYSTEM plugin."""
92
        stats_to_check = ['hostname', 'os_name']
93
        print('INFO: [TEST_002] Check SYSTEM stats: %s' % ', '.join(stats_to_check))
94
        stats_grab = stats.get_plugin('system').get_raw()
95
        for stat in stats_to_check:
96
            # Check that the key exist
97
            self.assertTrue(stat in stats_grab, msg='Cannot find key: %s' % stat)
98
        print('INFO: SYSTEM stats: %s' % stats_grab)
99
100
    def test_003_cpu(self):
101
        """Check CPU plugin."""
102
        stats_to_check = ['system', 'user', 'idle']
103
        print('INFO: [TEST_003] Check mandatory CPU stats: %s' % ', '.join(stats_to_check))
104
        stats_grab = stats.get_plugin('cpu').get_raw()
105
        for stat in stats_to_check:
106
            # Check that the key exist
107
            self.assertTrue(stat in stats_grab, msg='Cannot find key: %s' % stat)
108
            # Check that % is > 0 and < 100
109
            self.assertGreaterEqual(stats_grab[stat], 0)
110
            self.assertLessEqual(stats_grab[stat], 100)
111
        print('INFO: CPU stats: %s' % stats_grab)
112
113
    @unittest.skipIf(WINDOWS, "Load average not available on Windows")
114
    def test_004_load(self):
115
        """Check LOAD plugin."""
116
        stats_to_check = ['cpucore', 'min1', 'min5', 'min15']
117
        print('INFO: [TEST_004] Check LOAD stats: %s' % ', '.join(stats_to_check))
118
        stats_grab = stats.get_plugin('load').get_raw()
119
        for stat in stats_to_check:
120
            # Check that the key exist
121
            self.assertTrue(stat in stats_grab, msg='Cannot find key: %s' % stat)
122
            # Check that % is > 0
123
            self.assertGreaterEqual(stats_grab[stat], 0)
124
        print('INFO: LOAD stats: %s' % stats_grab)
125
126
    def test_005_mem(self):
127
        """Check MEM plugin."""
128
        stats_to_check = ['available', 'used', 'free', 'total']
129
        print('INFO: [TEST_005] Check MEM stats: %s' % ', '.join(stats_to_check))
130
        stats_grab = stats.get_plugin('mem').get_raw()
131
        for stat in stats_to_check:
132
            # Check that the key exist
133
            self.assertTrue(stat in stats_grab, msg='Cannot find key: %s' % stat)
134
            # Check that % is > 0
135
            self.assertGreaterEqual(stats_grab[stat], 0)
136
        print('INFO: MEM stats: %s' % stats_grab)
137
138
    def test_006_swap(self):
139
        """Check MEMSWAP plugin."""
140
        stats_to_check = ['used', 'free', 'total']
141
        print('INFO: [TEST_006] Check SWAP stats: %s' % ', '.join(stats_to_check))
142
        stats_grab = stats.get_plugin('memswap').get_raw()
143
        for stat in stats_to_check:
144
            # Check that the key exist
145
            self.assertTrue(stat in stats_grab, msg='Cannot find key: %s' % stat)
146
            # Check that % is > 0
147
            self.assertGreaterEqual(stats_grab[stat], 0)
148
        print('INFO: SWAP stats: %s' % stats_grab)
149
150
    def test_007_network(self):
151
        """Check NETWORK plugin."""
152
        print('INFO: [TEST_007] Check NETWORK stats')
153
        stats_grab = stats.get_plugin('network').get_raw()
154
        self.assertTrue(type(stats_grab) is list, msg='Network stats is not a list')
155
        print('INFO: NETWORK stats: %s' % stats_grab)
156
157
    def test_008_diskio(self):
158
        """Check DISKIO plugin."""
159
        print('INFO: [TEST_008] Check DISKIO stats')
160
        stats_grab = stats.get_plugin('diskio').get_raw()
161
        self.assertTrue(type(stats_grab) is list, msg='DiskIO stats is not a list')
162
        print('INFO: diskio stats: %s' % stats_grab)
163
164
    def test_009_fs(self):
165
        """Check File System plugin."""
166
        # stats_to_check = [ ]
167
        print('INFO: [TEST_009] Check FS stats')
168
        stats_grab = stats.get_plugin('fs').get_raw()
169
        self.assertTrue(type(stats_grab) is list, msg='FileSystem stats is not a list')
170
        print('INFO: FS stats: %s' % stats_grab)
171
172
    def test_010_processes(self):
173
        """Check Process plugin."""
174
        # stats_to_check = [ ]
175
        print('INFO: [TEST_010] Check PROCESS stats')
176
        stats_grab = stats.get_plugin('processcount').get_raw()
177
        # total = stats_grab['total']
178
        self.assertTrue(type(stats_grab) is dict, msg='Process count stats is not a dict')
179
        print('INFO: PROCESS count stats: %s' % stats_grab)
180
        stats_grab = stats.get_plugin('processlist').get_raw()
181
        self.assertTrue(type(stats_grab) is list, msg='Process count stats is not a list')
182
        print('INFO: PROCESS list stats: %s items in the list' % len(stats_grab))
183
        # Check if number of processes in the list equal counter
184
        # self.assertEqual(total, len(stats_grab))
185
186
    def test_011_folders(self):
187
        """Check File System plugin."""
188
        # stats_to_check = [ ]
189
        print('INFO: [TEST_011] Check FOLDER stats')
190
        stats_grab = stats.get_plugin('folders').get_raw()
191
        self.assertTrue(type(stats_grab) is list, msg='Folders stats is not a list')
192
        print('INFO: Folders stats: %s' % stats_grab)
193
194
    def test_012_ip(self):
195
        """Check IP plugin."""
196
        print('INFO: [TEST_012] Check IP stats')
197
        stats_grab = stats.get_plugin('ip').get_raw()
198
        self.assertTrue(type(stats_grab) is dict, msg='IP stats is not a dict')
199
        print('INFO: IP stats: %s' % stats_grab)
200
201
    @unittest.skipIf(not LINUX, "IRQs available only on Linux")
202
    def test_013_irq(self):
203
        """Check IRQ plugin."""
204
        print('INFO: [TEST_013] Check IRQ stats')
205
        stats_grab = stats.get_plugin('irq').get_raw()
206
        self.assertTrue(type(stats_grab) is list, msg='IRQ stats is not a list')
207
        print('INFO: IRQ stats: %s' % stats_grab)
208
209
    @unittest.skipIf(not LINUX, "GPU available only on Linux")
210
    def test_013_gpu(self):
211
        """Check GPU plugin."""
212
        print('INFO: [TEST_014] Check GPU stats')
213
        stats_grab = stats.get_plugin('gpu').get_raw()
214
        self.assertTrue(type(stats_grab) is list, msg='GPU stats is not a list')
215
        print('INFO: GPU stats: %s' % stats_grab)
216
217
    def test_014_sorted_stats(self):
218
        """Check sorted stats method."""
219
        print('INFO: [TEST_015] Check sorted stats method')
220
        aliases = {
221
            "key2": "alias11",
222
            "key5": "alias2",
223
        }
224
        unsorted_stats = [
225
            {"key": "key4"},
226
            {"key": "key2"},
227
            {"key": "key5"},
228
            {"key": "key21"},
229
            {"key": "key3"},
230
        ]
231
232
        gp = GlancesPlugin()
233
        gp.get_key = lambda: "key"
234
        gp.has_alias = aliases.get
235
        gp.stats = unsorted_stats
236
237
        sorted_stats = gp.sorted_stats()
238
        self.assertEqual(len(sorted_stats), 5)
239
        self.assertEqual(sorted_stats[0]["key"], "key5")
240
        self.assertEqual(sorted_stats[1]["key"], "key2")
241
        self.assertEqual(sorted_stats[2]["key"], "key3")
242
        self.assertEqual(sorted_stats[3]["key"], "key4")
243
        self.assertEqual(sorted_stats[4]["key"], "key21")
244
245
    def test_015_subsample(self):
246
        """Test subsampling function."""
247
        print('INFO: [TEST_015] Subsampling')
248
        for l_test in [([1, 2, 3], 4),
249
                       ([1, 2, 3, 4], 4),
250
                       ([1, 2, 3, 4, 5, 6, 7], 4),
251
                       ([1, 2, 3, 4, 5, 6, 7, 8], 4),
252
                       (list(range(1, 800)), 4),
253
                       (list(range(1, 8000)), 800)]:
254
            l_subsample = subsample(l_test[0], l_test[1])
255
            self.assertLessEqual(len(l_subsample), l_test[1])
256
257
    def test_016_hddsmart(self):
258
        """Check hard disk SMART data plugin."""
259
        try:
260
            from glances.compat import is_admin
261
        except ImportError:
262
            print("INFO: [TEST_016] pySMART not found, not running SMART plugin test")
263
            return
264
265
        stat = 'DeviceName'
266
        print('INFO: [TEST_016] Check SMART stats: {}'.format(stat))
267
        stats_grab = stats.get_plugin('smart').get_raw()
268
        if not is_admin():
269
            print("INFO: Not admin, SMART list should be empty")
270
            assert len(stats_grab) == 0
271
        elif stats_grab == {}:
272
            print("INFO: Admin but SMART list is empty")
273
            assert len(stats_grab) == 0
274
        else:
275
            print(stats_grab)
276
            self.assertTrue(stat in stats_grab[0].keys(), msg='Cannot find key: %s' % stat)
277
278
        print('INFO: SMART stats: %s' % stats_grab)
279
280
    def test_094_thresholds(self):
281
        """Test thresholds classes"""
282
        print('INFO: [TEST_094] Thresholds')
283
        ok = GlancesThresholdOk()
284
        careful = GlancesThresholdCareful()
285
        warning = GlancesThresholdWarning()
286
        critical = GlancesThresholdCritical()
287
        self.assertTrue(ok < careful)
288
        self.assertTrue(careful < warning)
289
        self.assertTrue(warning < critical)
290
        self.assertFalse(ok > careful)
291
        self.assertEqual(ok, ok)
292
        self.assertEqual(str(ok), 'OK')
293
        thresholds = GlancesThresholds()
294
        thresholds.add('cpu_percent', 'OK')
295
        self.assertEqual(thresholds.get(stat_name='cpu_percent').description(), 'OK')
296
297
    def test_095_methods(self):
298
        """Test mandatories methods"""
299
        print('INFO: [TEST_095] Mandatories methods')
300
        mandatories_methods = ['reset', 'update']
301
        plugins_list = stats.getPluginsList()
302
        for plugin in plugins_list:
303
            for method in mandatories_methods:
304
                self.assertTrue(hasattr(stats.get_plugin(plugin), method),
305
                                msg='{} has no method {}()'.format(plugin, method))
306
307
    def test_096_views(self):
308
        """Test get_views method"""
309
        print('INFO: [TEST_096] Test views')
310
        plugins_list = stats.getPluginsList()
311
        for plugin in plugins_list:
312
            stats.get_plugin(plugin).get_raw()
313
            views_grab = stats.get_plugin(plugin).get_views()
314
            self.assertTrue(type(views_grab) is dict,
315
                            msg='{} view is not a dict'.format(plugin))
316
317
    def test_097_attribute(self):
318
        """Test GlancesAttribute classe"""
319
        print('INFO: [TEST_097] Test attribute')
320
        # GlancesAttribute
321
        from glances.attribute import GlancesAttribute
322
        a = GlancesAttribute('a', description='ad', history_max_size=3)
323
        self.assertEqual(a.name, 'a')
324
        self.assertEqual(a.description, 'ad')
325
        a.description = 'adn'
326
        self.assertEqual(a.description, 'adn')
327
        a.value = 1
328
        a.value = 2
329
        self.assertEqual(len(a.history), 2)
330
        a.value = 3
331
        self.assertEqual(len(a.history), 3)
332
        a.value = 4
333
        # Check if history_max_size=3 is OK
334
        self.assertEqual(len(a.history), 3)
335
        self.assertEqual(a.history_size(), 3)
336
        self.assertEqual(a.history_len(), 3)
337
        self.assertEqual(a.history_value()[1], 4)
338
        self.assertEqual(a.history_mean(nb=3), 4.5)
339
340
    def test_098_history(self):
341
        """Test GlancesHistory classe"""
342
        print('INFO: [TEST_098] Test history')
343
        # GlancesHistory
344
        from glances.history import GlancesHistory
345
        h = GlancesHistory()
346
        h.add('a', 1)
347
        h.add('a', 2)
348
        h.add('a', 3)
349
        h.add('b', 10)
350
        h.add('b', 20)
351
        h.add('b', 30)
352
        self.assertEqual(len(h.get()), 2)
353
        self.assertEqual(len(h.get()['a']), 3)
354
        h.reset()
355
        self.assertEqual(len(h.get()), 2)
356
        self.assertEqual(len(h.get()['a']), 0)
357
358
    def test_099_output_bars_must_be_between_0_and_100_percent(self):
359
        """Test quick look plugin.
360
361
        > bar.min_value
362
        0
363
        > bar.max_value
364
        100
365
        > bar.percent = -1
366
        > bar.percent
367
        0
368
        > bar.percent = 101
369
        > bar.percent
370
        100
371
        """
372
        print('INFO: [TEST_099] Test progress bar')
373
        bar = Bar(size=1)
374
        bar.percent = -1
375
        self.assertLessEqual(bar.percent, bar.min_value)
376
        bar.percent = 101
377
        self.assertGreaterEqual(bar.percent, bar.max_value)
378
379
    def test_100_secure(self):
380
        """Test secure functions"""
381
        print('INFO: [TEST_100] Secure functions')
382
        self.assertEqual(secure_popen('echo -n TEST'), 'TEST')
383
        self.assertEqual(secure_popen('echo FOO | grep FOO'), 'FOO\n')
384
        self.assertEqual(secure_popen('echo -n TEST1 && echo -n TEST2'), 'TEST1TEST2')
385
386
    def test_999_the_end(self):
387
        """Free all the stats"""
388
        print('INFO: [TEST_999] Free the stats')
389
        stats.end()
390
        self.assertTrue(True)
391
392
393
if __name__ == '__main__':
394
    unittest.main()
395