5
5
import os
6
6
from pathlib import Path
7
7
import shutil
8
- import subprocess
9
- from subprocess import CompletedProcess
10
8
from typing import Any , Callable , IO , NamedTuple , Optional , Union
11
9
12
10
from _pytest .monkeypatch import MonkeyPatch
@@ -98,7 +96,12 @@ class TestRelay:
98
96
FILDIR_SWITCH = "--files-directory"
99
97
BDEBUG_SWITCH = "--debug"
100
98
101
- DISK_STR = "We've got disk!"
99
+ FAKE_DISK_UTL = {
100
+ "bytes_used" : 1200000 ,
101
+ "bytes_remaining" : 80000000000 ,
102
+ "string" : "0.00001% full, 80Gb remaining" ,
103
+ }
104
+
102
105
END_OF_MAIN = AssertionError ("Unexpectedly reached the body of main()" )
103
106
SERVER_ID_TEXT = "ThisIsMyServerServerID"
104
107
@@ -170,10 +173,10 @@ def do_setup(
170
173
- pathlib.Path.open()
171
174
- pathlib.Path.unlink()
172
175
- the Path "/" operators
173
- - relay.get_disk_utilization_str ()
176
+ - relay.get_disk_utilization ()
174
177
175
178
The mock classes seem to be necessary in order to intercept the
176
- respective member functions, possibly because these native
179
+ respective member functions, possibly because these are native
177
180
implementations instead of "pure Python" (or, maybe I just don't
178
181
know what I'm doing).
179
182
@@ -331,19 +334,19 @@ def unlink(self, *args, **kwargs):
331
334
else :
332
335
return self .path .unlink (* args , ** kwargs )
333
336
334
- def mock_get_disk_utilization_str (dir_path : Path ) -> str :
335
- """Mock for relay.get_disk_utilization_str ()
337
+ def mock_get_disk_utilization (dir_path : Path ) -> dict [ str , int | str ] :
338
+ """Mock for relay.get_disk_utilization ()
336
339
337
340
Returns a static string.
338
341
339
342
Note that if the assertion fails, the exception will be caught and
340
343
reported as an INTERNAL_SERVER_ERROR. This will likely make the
341
- test fail, but only if it's checking the response....
344
+ test fail, but only if it's actually checking the response....
342
345
"""
343
346
assert str (dir_path ) == relay .DEFAULT_FILES_DIRECTORY
344
- return TestRelay .DISK_STR
347
+ return TestRelay .FAKE_DISK_UTL
345
348
346
- m .setattr (relay , "get_disk_utilization_str " , mock_get_disk_utilization_str )
349
+ m .setattr (relay , "get_disk_utilization " , mock_get_disk_utilization )
347
350
m .setattr (relay , "Path" , MockPath )
348
351
m .setattr (relay , "sha256" , lambda * _args , ** _kwargs : MockHash ())
349
352
m .setattr (relay .app , "run" , func )
@@ -490,28 +493,13 @@ def test_command_with_server_error(monkeypatch: MonkeyPatch):
490
493
TestRelay .check_result (result , exit_code = 2 , stderr = "Error running the server" )
491
494
492
495
@staticmethod
493
- @pytest .mark .parametrize (
494
- "files_str,returncode" ,
495
- (("We've got files!" , 0 ), ("We've got NO files!" , 1 )),
496
- )
497
- def test_relay_status_operation (
498
- files_str : str , returncode : int , monkeypatch : MonkeyPatch
499
- ):
496
+ def test_relay_status_operation (monkeypatch : MonkeyPatch ):
500
497
"""Test GET /<server_id> method operation"""
501
498
502
- def mock_run (args : Union [str , list [str ]], * , cwd : str , ** _kwargs ):
503
- """Mock for subprocess.run()"""
504
- assert str (cwd ) == relay .DEFAULT_FILES_DIRECTORY
505
- key = "stdout" if returncode == 0 else "stderr"
506
- kwargs = {"args" : args , "returncode" : returncode , key : files_str }
507
- return CompletedProcess (** kwargs )
508
-
509
499
def validate_relay (response : HTTPResponse ):
510
500
"""Validate the response from the HTTP method call"""
511
501
assert response .status_code == HTTPStatus .OK
512
- assert TestRelay .DISK_STR in response .body ["disk utilization" ]
513
- key = "files" if returncode == 0 else "error"
514
- assert files_str in response .body [key ]
502
+ assert response .body ["disk utilization" ] == TestRelay .FAKE_DISK_UTL
515
503
516
504
with monkeypatch .context () as m :
517
505
mock = mock_app_method_call (
@@ -520,7 +508,6 @@ def validate_relay(response: HTTPResponse):
520
508
method_args = {"server_id" : TestRelay .SERVER_ID_TEXT },
521
509
)
522
510
TestRelay .do_setup (m , func = mock )
523
- m .setattr (subprocess , "run" , mock_run )
524
511
result = TestRelay .invoke_main ()
525
512
TestRelay .check_result (result )
526
513
@@ -853,8 +840,8 @@ def validate_receive_file(response: HTTPResponse):
853
840
assert request .content_length == bytes_written [0 ]
854
841
855
842
@staticmethod
856
- def test_get_disk_utilization_str (monkeypatch : MonkeyPatch ):
857
- """Exercise get_disk_utilization_str ()
843
+ def test_get_disk_utilization (monkeypatch : MonkeyPatch ):
844
+ """Exercise get_disk_utilization ()
858
845
859
846
This is a (nearly) trivial function, but we test it so that the unit
860
847
tests show 100% coverage of the CUT.
@@ -867,6 +854,7 @@ class DiskUsageData(NamedTuple):
867
854
868
855
expected_dir_path = Path ("/mockdir" )
869
856
du = DiskUsageData ()
857
+ nv = "3.2 GB"
870
858
871
859
def mock_disk_usage (dir_path : Path ) -> DiskUsageData :
872
860
"""Mock shutil.disk_usage()"""
@@ -877,13 +865,20 @@ def mock_naturalsize(value: Union[float, str], *args):
877
865
"""Mock humanize.naturalsize()"""
878
866
assert len (args ) == 0
879
867
assert str (value ) == str (du .free )
880
- return "3.2 GB"
868
+ return nv
881
869
882
870
with monkeypatch .context () as m :
883
871
m .setattr (shutil , "disk_usage" , mock_disk_usage )
884
872
m .setattr (humanize , "naturalsize" , mock_naturalsize )
885
- expected = "40.0% full, 3.2 GB remaining"
886
- actual = relay .get_disk_utilization_str (expected_dir_path )
873
+ expected = {
874
+ "bytes_used" : du .used ,
875
+ "bytes_remaining" : du .free ,
876
+ "string" : "{:.3}% full, {} remaining" .format (
877
+ float (du .used ) / float (du .total ) * 100.0 ,
878
+ nv ,
879
+ ),
880
+ }
881
+ actual = relay .get_disk_utilization (expected_dir_path )
887
882
assert actual == expected
888
883
889
884
@staticmethod
0 commit comments