@@ -56,6 +56,21 @@ def check_dom0(self, dom0):
56
56
),
57
57
)
58
58
59
+ def assertExpectedStdout (self , target , expected_stdout : bytes , * , exit_code = 0 ):
60
+ messages = util .sort_messages (target .recv_all_messages ())
61
+ self .assertListEqual (messages [- 3 :],
62
+ [
63
+ (qrexec .MSG_DATA_STDOUT , b"" ),
64
+ (qrexec .MSG_DATA_STDERR , b"" ),
65
+ (qrexec .MSG_DATA_EXIT_CODE , struct .pack ("<L" , exit_code ))
66
+ ])
67
+ stdout_entries = []
68
+ for msg_type , msg_body in messages [:- 3 ]:
69
+ # messages before last are not empty, hence truthy
70
+ self .assertTrue (msg_body )
71
+ self .assertEqual (msg_type , qrexec .MSG_DATA_STDOUT )
72
+ stdout_entries .append (msg_body )
73
+
59
74
def setUp (self ):
60
75
self .tempdir = tempfile .mkdtemp ()
61
76
os .mkdir (os .path .join (self .tempdir , "local-rpc" ))
@@ -188,16 +203,7 @@ def test_exec_cmdline(self):
188
203
189
204
target .send_message (qrexec .MSG_DATA_STDIN , b"" )
190
205
191
- messages = target .recv_all_messages ()
192
- self .assertListEqual (
193
- util .sort_messages (messages ),
194
- [
195
- (qrexec .MSG_DATA_STDOUT , b"Hello world\n " ),
196
- (qrexec .MSG_DATA_STDOUT , b"" ),
197
- (qrexec .MSG_DATA_STDERR , b"" ),
198
- (qrexec .MSG_DATA_EXIT_CODE , b"\0 \0 \0 \0 " ),
199
- ],
200
- )
206
+ self .assertExpectedStdout (target , b"Hello world\n " )
201
207
self .check_dom0 (dom0 )
202
208
203
209
def test_trigger_service (self ):
@@ -314,16 +320,7 @@ def test_exec_service(self):
314
320
)
315
321
target , dom0 = self .execute_qubesrpc ("qubes.Service+arg" , "domX" )
316
322
target .send_message (qrexec .MSG_DATA_STDIN , b"" )
317
- messages = target .recv_all_messages ()
318
- self .assertListEqual (
319
- util .sort_messages (messages ),
320
- [
321
- (qrexec .MSG_DATA_STDOUT , b"arg: arg, remote domain: domX\n " ),
322
- (qrexec .MSG_DATA_STDOUT , b"" ),
323
- (qrexec .MSG_DATA_STDERR , b"" ),
324
- (qrexec .MSG_DATA_EXIT_CODE , b"\0 \0 \0 \0 " ),
325
- ],
326
- )
323
+ self .assertExpectedStdout (target , b"arg: arg, remote domain: domX\n " )
327
324
self .check_dom0 (dom0 )
328
325
329
326
def test_exec_service_keyword (self ):
@@ -342,20 +339,11 @@ def test_exec_service_keyword(self):
342
339
)
343
340
target , dom0 = self .execute_qubesrpc ("qubes.Service" , "domX" )
344
341
target .send_message (qrexec .MSG_DATA_STDIN , b"" )
345
- messages = target .recv_all_messages ()
346
- self .assertListEqual (
347
- util .sort_messages (messages ),
348
- [
349
- (qrexec .MSG_DATA_STDOUT , b"""arg: , remote domain: domX
342
+ self .assertExpectedStdout (target , b"""arg: , remote domain: domX
350
343
target name: NONAME
351
344
target keyword: NOKEYWORD
352
345
target type: ''
353
- """ ),
354
- (qrexec .MSG_DATA_STDOUT , b"" ),
355
- (qrexec .MSG_DATA_STDERR , b"" ),
356
- (qrexec .MSG_DATA_EXIT_CODE , b"\0 \0 \0 \0 " ),
357
- ],
358
- )
346
+ """ )
359
347
self .check_dom0 (dom0 )
360
348
361
349
def test_exec_service_with_config (self ):
@@ -376,16 +364,7 @@ def test_exec_service_with_config(self):
376
364
""" )
377
365
target , dom0 = self .execute_qubesrpc ("qubes.Service+arg" , "domX" )
378
366
target .send_message (qrexec .MSG_DATA_STDIN , b"" )
379
- messages = target .recv_all_messages ()
380
- self .assertListEqual (
381
- util .sort_messages (messages ),
382
- [
383
- (qrexec .MSG_DATA_STDOUT , b"arg: arg, remote domain: domX\n " ),
384
- (qrexec .MSG_DATA_STDOUT , b"" ),
385
- (qrexec .MSG_DATA_STDERR , b"" ),
386
- (qrexec .MSG_DATA_EXIT_CODE , b"\0 \0 \0 \0 " ),
387
- ],
388
- )
367
+ self .assertExpectedStdout (target , b"arg: arg, remote domain: domX\n " )
389
368
self .check_dom0 (dom0 )
390
369
391
370
def test_wait_for_session (self ):
@@ -449,20 +428,9 @@ def _test_wait_for_session(self, config_name, service_name="qubes.Service", argu
449
428
# Do not send EOF. Shell read doesn't need it, and this checks that
450
429
# qrexec does not wait for EOF on stdin before sending the exit code
451
430
# from the remote process.
452
- messages = target .recv_all_messages ()
453
- self .assertListEqual (
454
- util .sort_messages (messages ),
455
- [
456
- (
457
- qrexec .MSG_DATA_STDOUT ,
458
- b"arg: " + argument .encode ("ascii" , "strict" )
459
- + b", remote domain: domX, input: stdin data\n " ,
460
- ),
461
- (qrexec .MSG_DATA_STDOUT , b"" ),
462
- (qrexec .MSG_DATA_STDERR , b"" ),
463
- (qrexec .MSG_DATA_EXIT_CODE , b"\0 \0 \0 \0 " ),
464
- ],
465
- )
431
+ expected_stdout = (b"arg: " + argument .encode ("ascii" , "strict" )
432
+ + b", remote domain: domX, input: stdin data\n " )
433
+ self .assertExpectedStdout (target , expected_stdout )
466
434
self .check_dom0 (dom0 )
467
435
468
436
def test_exec_service_fail (self ):
@@ -599,16 +567,7 @@ def test_exec_null_argument_finds_service_for_empty_argument(self):
599
567
)
600
568
target , dom0 = self .execute_qubesrpc ("qubes.Service" , "domX" )
601
569
target .send_message (qrexec .MSG_DATA_STDIN , b"" )
602
- messages = target .recv_all_messages ()
603
- self .assertListEqual (
604
- util .sort_messages (messages ),
605
- [
606
- (qrexec .MSG_DATA_STDOUT , b"specific service: qubes.Service\n " ),
607
- (qrexec .MSG_DATA_STDOUT , b"" ),
608
- (qrexec .MSG_DATA_STDERR , b"" ),
609
- (qrexec .MSG_DATA_EXIT_CODE , b"\0 \0 \0 \0 " ),
610
- ],
611
- )
570
+ self .assertExpectedStdout (target , b"specific service: qubes.Service\n " )
612
571
self .check_dom0 (dom0 )
613
572
614
573
def test_socket_null_argument_finds_service_for_empty_argument (self ):
@@ -806,16 +765,7 @@ def test_pass_stdin(self):
806
765
)
807
766
808
767
target .send_message (qrexec .MSG_DATA_STDIN , b"" )
809
- messages = target .recv_all_messages ()
810
- self .assertListEqual (
811
- util .sort_messages (messages ),
812
- [
813
- (qrexec .MSG_DATA_STDOUT , b"" ),
814
- (qrexec .MSG_DATA_STDERR , b"" ),
815
- (qrexec .MSG_DATA_EXIT_CODE , b"\0 \0 \0 \0 " ),
816
- ],
817
- )
818
- self .check_dom0 (dom0 )
768
+ self .assertExpectedStdout (target , b"" )
819
769
820
770
def test_close_stdin_early (self ):
821
771
# Make sure that we cover the error on writing stdin into living
@@ -835,15 +785,7 @@ def test_close_stdin_early(self):
835
785
target .send_message (qrexec .MSG_DATA_STDIN , b"data 2\n " )
836
786
target .send_message (qrexec .MSG_DATA_STDIN , b"" )
837
787
838
- messages = target .recv_all_messages ()
839
- self .assertListEqual (
840
- util .sort_messages (messages ),
841
- [
842
- (qrexec .MSG_DATA_STDOUT , b"" ),
843
- (qrexec .MSG_DATA_STDERR , b"" ),
844
- (qrexec .MSG_DATA_EXIT_CODE , b"\0 \0 \0 \0 " ),
845
- ],
846
- )
788
+ self .assertExpectedStdout (target , b"" )
847
789
self .check_dom0 (dom0 )
848
790
849
791
def test_buffer_stdin (self ):
@@ -871,29 +813,7 @@ def test_buffer_stdin(self):
871
813
with open (fifo , "a" ) as f :
872
814
f .write ("end\n " )
873
815
f .flush ()
874
-
875
- messages = []
876
- received_data = b""
877
- while len (received_data ) < data_size :
878
- message_type , message = target .recv_message ()
879
- if message_type != qrexec .MSG_DATA_STDOUT :
880
- messages .append ((message_type , message ))
881
- else :
882
- self .assertEqual (message_type , qrexec .MSG_DATA_STDOUT )
883
- received_data += message
884
-
885
- self .assertEqual (len (received_data ), data_size )
886
- self .assertEqual (received_data , data )
887
-
888
- messages += target .recv_all_messages ()
889
- self .assertListEqual (
890
- util .sort_messages (messages ),
891
- [
892
- (qrexec .MSG_DATA_STDOUT , b"" ),
893
- (qrexec .MSG_DATA_STDERR , b"" ),
894
- (qrexec .MSG_DATA_EXIT_CODE , b"\0 \0 \0 \0 " ),
895
- ],
896
- )
816
+ self .assertExpectedStdout (target , data )
897
817
self .check_dom0 (dom0 )
898
818
899
819
def test_close_stdout_stderr_early (self ):
@@ -948,16 +868,7 @@ def test_stdio_socket(self):
948
868
target .send_message (qrexec .MSG_DATA_STDIN , b"stdin\n " )
949
869
target .send_message (qrexec .MSG_DATA_STDIN , b"" )
950
870
951
- messages = target .recv_all_messages ()
952
- self .assertListEqual (
953
- util .sort_messages (messages ),
954
- [
955
- (qrexec .MSG_DATA_STDOUT , b"received: stdin\n " ),
956
- (qrexec .MSG_DATA_STDOUT , b"" ),
957
- (qrexec .MSG_DATA_STDERR , b"" ),
958
- (qrexec .MSG_DATA_EXIT_CODE , b"\0 \0 \0 \0 " ),
959
- ],
960
- )
871
+ self .assertExpectedStdout (target , b"received: stdin\n " )
961
872
self .check_dom0 (dom0 )
962
873
963
874
def test_exit_before_closing_streams (self ):
@@ -995,18 +906,7 @@ def test_exit_before_closing_streams(self):
995
906
with open (fifo , "a" ) as f :
996
907
f .write ("end\n " )
997
908
f .flush ()
998
- self .assertEqual (
999
- target .recv_message (), (qrexec .MSG_DATA_STDOUT , b"child exiting\n " )
1000
- )
1001
- messages = target .recv_all_messages ()
1002
- self .assertListEqual (
1003
- util .sort_messages (messages ),
1004
- [
1005
- (qrexec .MSG_DATA_STDOUT , b"" ),
1006
- (qrexec .MSG_DATA_STDERR , b"" ),
1007
- (qrexec .MSG_DATA_EXIT_CODE , struct .pack ("<L" , 42 )),
1008
- ],
1009
- )
909
+ self .assertExpectedStdout (target , b"child exiting\n " , exit_code = 42 )
1010
910
self .check_dom0 (dom0 )
1011
911
1012
912
0 commit comments