55import os
66from pathlib import Path
77import shutil
8- import subprocess
9- from subprocess import CompletedProcess
108from typing import Any , Callable , IO , NamedTuple , Optional , Union
119
1210from _pytest .monkeypatch import MonkeyPatch
@@ -98,7 +96,12 @@ class TestRelay:
9896 FILDIR_SWITCH = "--files-directory"
9997 BDEBUG_SWITCH = "--debug"
10098
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+
102105 END_OF_MAIN = AssertionError ("Unexpectedly reached the body of main()" )
103106 SERVER_ID_TEXT = "ThisIsMyServerServerID"
104107
@@ -170,10 +173,10 @@ def do_setup(
170173 - pathlib.Path.open()
171174 - pathlib.Path.unlink()
172175 - the Path "/" operators
173- - relay.get_disk_utilization_str ()
176+ - relay.get_disk_utilization ()
174177
175178 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
177180 implementations instead of "pure Python" (or, maybe I just don't
178181 know what I'm doing).
179182
@@ -331,19 +334,19 @@ def unlink(self, *args, **kwargs):
331334 else :
332335 return self .path .unlink (* args , ** kwargs )
333336
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 ()
336339
337340 Returns a static string.
338341
339342 Note that if the assertion fails, the exception will be caught and
340343 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....
342345 """
343346 assert str (dir_path ) == relay .DEFAULT_FILES_DIRECTORY
344- return TestRelay .DISK_STR
347+ return TestRelay .FAKE_DISK_UTL
345348
346- m .setattr (relay , "get_disk_utilization_str " , mock_get_disk_utilization_str )
349+ m .setattr (relay , "get_disk_utilization " , mock_get_disk_utilization )
347350 m .setattr (relay , "Path" , MockPath )
348351 m .setattr (relay , "sha256" , lambda * _args , ** _kwargs : MockHash ())
349352 m .setattr (relay .app , "run" , func )
@@ -490,28 +493,13 @@ def test_command_with_server_error(monkeypatch: MonkeyPatch):
490493 TestRelay .check_result (result , exit_code = 2 , stderr = "Error running the server" )
491494
492495 @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 ):
500497 """Test GET /<server_id> method operation"""
501498
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-
509499 def validate_relay (response : HTTPResponse ):
510500 """Validate the response from the HTTP method call"""
511501 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
515503
516504 with monkeypatch .context () as m :
517505 mock = mock_app_method_call (
@@ -520,7 +508,6 @@ def validate_relay(response: HTTPResponse):
520508 method_args = {"server_id" : TestRelay .SERVER_ID_TEXT },
521509 )
522510 TestRelay .do_setup (m , func = mock )
523- m .setattr (subprocess , "run" , mock_run )
524511 result = TestRelay .invoke_main ()
525512 TestRelay .check_result (result )
526513
@@ -853,8 +840,8 @@ def validate_receive_file(response: HTTPResponse):
853840 assert request .content_length == bytes_written [0 ]
854841
855842 @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 ()
858845
859846 This is a (nearly) trivial function, but we test it so that the unit
860847 tests show 100% coverage of the CUT.
@@ -867,6 +854,7 @@ class DiskUsageData(NamedTuple):
867854
868855 expected_dir_path = Path ("/mockdir" )
869856 du = DiskUsageData ()
857+ nv = "3.2 GB"
870858
871859 def mock_disk_usage (dir_path : Path ) -> DiskUsageData :
872860 """Mock shutil.disk_usage()"""
@@ -877,13 +865,20 @@ def mock_naturalsize(value: Union[float, str], *args):
877865 """Mock humanize.naturalsize()"""
878866 assert len (args ) == 0
879867 assert str (value ) == str (du .free )
880- return "3.2 GB"
868+ return nv
881869
882870 with monkeypatch .context () as m :
883871 m .setattr (shutil , "disk_usage" , mock_disk_usage )
884872 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 )
887882 assert actual == expected
888883
889884 @staticmethod
0 commit comments