Skip to content

Commit 9ba3625

Browse files
committed
Add tests for various command line options
1 parent 09930c5 commit 9ba3625

File tree

2 files changed

+63
-21
lines changed

2 files changed

+63
-21
lines changed

gpustat/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def main(*argv):
9595
action='store_true', help='Display GPU fan speed')
9696
parser.add_argument(
9797
'-e', '--show-codec', nargs='?', const='enc,dec', default='',
98-
choices=['enc', 'dec', 'enc,dec'],
98+
choices=['', 'enc', 'dec', 'enc,dec'],
9999
help='Show encoder/decoder utilization'
100100
)
101101
parser.add_argument(

gpustat/test_gpustat.py

Lines changed: 62 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import unittest
1010
import sys
1111
import os
12+
import shlex
1213
from collections import namedtuple
1314

1415
import psutil
@@ -151,7 +152,7 @@ def _decorated(*args, **kwargs):
151152
154213: ('user1', 'caffe', 16.89, 100.00),
152153
38310: ('user3', 'python', 26.23, 99.9653),
153154
153223: ('user2', 'python', 15.25, 0.0000),
154-
194826: ('user3', 'caffe', 0.0, 12.5236),
155+
194826: ('user3', '/local/bin/caffe', 0.0, 12.5236),
155156
192453: ('user1', 'torch', 123.2, 0.7312),
156157
}
157158

@@ -190,7 +191,7 @@ def _MockedMem():
190191
└─ 153223 ( 15%, 0B): python
191192
[1] GeForce GTX TITAN 1 | 36°C, 53 %, 0 % (E: 0 % D: 0 %), ?? / 250 W | 9000 / 12189 MB | user1:torch/192453(3000M) user3:caffe/194826(6000M)
192193
├─ 192453 ( 123%, 59MB): torch
193-
└─ 194826 ( 0%, 1025MB): caffe
194+
└─ 194826 ( 0%, 1025MB): /local/bin/caffe
194195
[2] GeForce GTX TITAN 2 | 71°C, 100 %, ?? % (E: ?? % D: ?? %), 250 / ?? W | 0 / 12189 MB | (Not Supported)
195196
""".splitlines()) # noqa: E501
196197

@@ -288,28 +289,29 @@ def test_attributes_and_items(self, N, Process, virtual_memory):
288289
print("utilization_enc : %s" % (g.utilization_enc))
289290
print("utilization_dec : %s" % (g.utilization_dec))
290291

292+
@staticmethod
293+
def capture_output(*args):
294+
f = StringIO()
295+
import contextlib
296+
297+
with contextlib.redirect_stdout(f): # requires python 3.4+
298+
try:
299+
gpustat.main(*args)
300+
except SystemExit as e:
301+
if e.code != 0:
302+
raise AssertionError(
303+
"Argparse failed (see above error message)")
304+
return f.getvalue()
305+
306+
291307
@unittest.skipIf(sys.version_info < (3, 4), "Only in Python 3.4+")
292308
@mock.patch('psutil.virtual_memory')
293309
@mock.patch('psutil.Process')
294310
@mock.patch('gpustat.core.N')
295-
def test_args_endtoend(self, N, Process, virtual_memory):
296-
"""
297-
End-to-end testing given command line args.
298-
"""
311+
def test_args_commandline(self, N, Process, virtual_memory):
312+
"""Tests the end gpustat CLI."""
299313
_configure_mock(N, Process, virtual_memory)
300-
301-
def capture_output(*args):
302-
f = StringIO()
303-
import contextlib
304-
305-
with contextlib.redirect_stdout(f): # requires python 3.4+
306-
try:
307-
gpustat.main(*args)
308-
except SystemExit:
309-
raise AssertionError(
310-
"Argparse failed (see above error message)"
311-
)
312-
return f.getvalue()
314+
capture_output = self.capture_output
313315

314316
def _remove_ansi_codes_and_header_line(s):
315317
unescaped = remove_ansi_codes(s)
@@ -322,6 +324,10 @@ def _remove_ansi_codes_and_header_line(s):
322324
self.assertEqual(_remove_ansi_codes_and_header_line(s),
323325
MOCK_EXPECTED_OUTPUT_DEFAULT)
324326

327+
s = capture_output('gpustat', '--version')
328+
assert s.startswith('gpustat ')
329+
print(s)
330+
325331
s = capture_output('gpustat', '--no-header')
326332
self.assertIn("[0]", s.splitlines()[0])
327333

@@ -340,6 +346,40 @@ def _remove_ansi_codes_and_header_line(s):
340346
self.assertEqual(_remove_ansi_codes_and_header_line(s),
341347
MOCK_EXPECTED_OUTPUT_DEFAULT)
342348

349+
@unittest.skipIf(sys.version_info < (3, 4), "Only in Python 3.4+")
350+
@mock.patch('psutil.virtual_memory')
351+
@mock.patch('psutil.Process')
352+
@mock.patch('gpustat.core.N')
353+
def test_args_commandline_showoptions(self, N, Process, virtual_memory):
354+
"""Tests gpustat CLI with a variety of --show-xxx options. """
355+
356+
_configure_mock(N, Process, virtual_memory)
357+
capture_output = self.capture_output
358+
print('')
359+
360+
TEST_OPTS = []
361+
TEST_OPTS += ['-a', '-c', '-u', '-p', '-e', '-P', '-f']
362+
TEST_OPTS += [('-e', ''), ('-P', '')]
363+
TEST_OPTS += [('-e', 'enc,dec'), '-Plimit,draw']
364+
TEST_OPTS += ['-cup', '-cpu', '-cufP'] # 'cpuePf'
365+
366+
for opt in TEST_OPTS:
367+
if isinstance(opt, str):
368+
opt = [opt]
369+
370+
print('\x1b[30m\x1b[43m', # black_on_yellow
371+
'$ gpustat ' + ' '.join(shlex.quote(o) for o in opt),
372+
'\x1b(B\x1b[m', sep='')
373+
s = capture_output('gpustat', *opt)
374+
375+
# TODO: Validate output without hardcoding expected outputs
376+
print(s)
377+
378+
# Finally, unknown args
379+
with self.assertRaises(AssertionError):
380+
capture_output('gpustat', '--unrecognized-args-in-test')
381+
382+
343383
@mock.patch('psutil.virtual_memory')
344384
@mock.patch('psutil.Process')
345385
@mock.patch('gpustat.core.N')
@@ -352,7 +392,9 @@ def test_json_mocked(self, N, Process, virtual_memory):
352392

353393
import json
354394
j = json.loads(fp.getvalue())
355-
print(j)
395+
396+
from pprint import pprint
397+
pprint(j)
356398

357399

358400
if __name__ == '__main__':

0 commit comments

Comments
 (0)