11#
22# The Qubes OS Project, https://www.qubes-os.org/
33#
4- # Copyright (C) 2025 Marek Marczykowski-Górecki
5- 4+ # Copyright (C) 2025 Benjamin Grande <[email protected] > 65#
76# This program is free software; you can redistribute it and/or modify
87# it under the terms of the GNU Lesser General Public License as published by
1918
2019import asyncio
2120import os
21+ import shutil
2222import sys
23- import time
23+ import tempfile
2424
2525import qubes .tests
2626
2727
2828class TC_00_DispVMPerfMixin :
2929 def setUp (self : qubes .tests .SystemTestCase ):
3030 super ().setUp ()
31+ self .results = os .getenv ("QUBES_TEST_PERF_FILE" )
32+ self .test_dir = None
33+ if "_reader" in self ._testMethodName :
34+ prefix = self .template + "_"
35+ if self .results :
36+ prefix = self .results + "_" + prefix
37+ self .test_dir = tempfile .mkdtemp (prefix = prefix )
38+ self .vm2 = None
39+ return
3140 if "whonix-g" in self .template :
3241 self .skipTest (
3342 "whonix gateway is not supported as DisposableVM Template"
@@ -53,32 +62,42 @@ def setUp(self: qubes.tests.SystemTestCase):
5362 template = self .app .domains [self .template ],
5463 default_dispvm = self .dvm ,
5564 )
65+ # Necessary to be done post qube creation because of Whonix Admin Addon:
66+ # https://github.com/QubesOS/qubes-core-admin-addon-whonix/pull/25
67+ for qube in [self .dvm , self .vm1 , self .vm2 ]:
68+ qube .default_dispvm = self .dvm
69+ qube .netvm = None
5670 self .loop .run_until_complete (
5771 asyncio .gather (
5872 self .dvm .create_on_disk (),
5973 self .vm1 .create_on_disk (),
6074 self .vm2 .create_on_disk (),
6175 )
6276 )
77+ self .loop .run_until_complete (self .start_vm (self .dvm ))
78+ self .shutdown_and_wait (self .dvm )
6379 start_tasks = [self .vm1 .start ()]
64- if self ._testMethodName . startswith ( "vm" ) :
80+ if "_vm" in self ._testMethodName :
6581 start_tasks .append (self .vm2 .start ())
6682 self .loop .run_until_complete (asyncio .gather (* start_tasks ))
6783
6884 def tearDown (self : qubes .tests .SystemTestCase ):
6985 super ().tearDown ()
70- if self .vm2 .is_running ():
71- self .loop .run_until_complete (
72- asyncio .gather (
73- self .vm2 .shutdown (),
86+ if self .test_dir and os .getenv ("QUBES_TEST_PERF_GRAPH_DELETE" ):
87+ shutil .rmtree (self .test_dir )
88+ if self .vm2 :
89+ if self .vm2 .is_running ():
90+ self .loop .run_until_complete (
91+ asyncio .gather (
92+ self .vm2 .shutdown (),
93+ )
7494 )
75- )
7695
7796 def run_test (self , name ):
7897 dvm = self .dvm .name
7998 vm1 = self .vm1 .name
8099 vm2 = ""
81- if name . startswith ( " vm") :
100+ if "- vm" in name :
82101 vm2 = self .vm2 .name
83102 cmd = [
84103 "/usr/lib/qubes/tests/dispvm_perf.py" ,
@@ -92,141 +111,169 @@ def run_test(self, name):
92111 if p .returncode :
93112 self .fail (f"'{ ' ' .join (cmd )} ' failed: { p .returncode } " )
94113
95- def test_000_dispvm (self ):
114+ def run_reader (self , args : list ):
115+ if not self .results :
116+ self .skipTest ("Did not set QUBES_TEST_PERF_FILE" )
117+ cmd = [
118+ "/usr/lib/qubes/tests/dispvm_perf_reader.py" ,
119+ f"--template={ self .template } " ,
120+ f"--output-dir={ self .test_dir } " ,
121+ * args ,
122+ "--" ,
123+ self .results ,
124+ ]
125+ p = self .loop .run_until_complete (asyncio .create_subprocess_exec (* cmd ))
126+ self .loop .run_until_complete (p .wait ())
127+ if p .returncode :
128+ self .fail (f"'{ ' ' .join (cmd )} ' failed: { p .returncode } " )
129+
130+ def test_000_vm_dispvm (self ):
96131 """Latency of vm-dispvm calls"""
97- self .run_test ("dispvm" )
132+ self .run_test ("vm- dispvm" )
98133
99- def test_001_dispvm_gui (self ):
134+ def test_001_vm_dispvm_gui (self ):
100135 """Latency of vm-dispvm GUI calls"""
101- self .run_test ("dispvm-gui" )
136+ self .run_test ("vm- dispvm-gui" )
102137
103- def test_002_dispvm_concurrent (self ):
138+ def test_002_vm_dispvm_concurrent (self ):
104139 """Latency of vm-dispvm concurrent calls"""
105- self .run_test ("dispvm-concurrent" )
140+ self .run_test ("vm- dispvm-concurrent" )
106141
107- def test_003_dispvm_gui_concurrent (self ):
142+ def test_003_vm_dispvm_gui_concurrent (self ):
108143 """Latency of vm-dispvm concurrent GUI calls"""
109- self .run_test ("dispvm-gui-concurrent" )
144+ self .run_test ("vm- dispvm-gui-concurrent" )
110145
111- def test_006_dispvm_from_dom0 (self ):
146+ def test_006_dom0_dispvm (self ):
112147 """Latency of dom0-dispvm calls"""
113- self .run_test ("dispvm- dom0" )
148+ self .run_test ("dom0-dispvm " )
114149
115- def test_007_dispvm_from_dom0_gui (self ):
150+ def test_007_dom0_dispvm_gui (self ):
116151 """Latency of dom0-dispvm GUI calls"""
117- self .run_test ("dispvm- dom0-gui" )
152+ self .run_test ("dom0-dispvm -gui" )
118153
119- def test_008_dispvm_from_dom0_concurrent (self ):
154+ def test_008_dom0_dispvm_concurrent (self ):
120155 """Latency of dom0-dispvm concurrent calls"""
121- self .run_test ("dispvm- dom0-concurrent" )
156+ self .run_test ("dom0-dispvm -concurrent" )
122157
123- def test_009_dispvm_from_dom0_gui_concurrent (self ):
158+ def test_009_dom0_dispvm_gui_concurrent (self ):
124159 """Latency of dom0-dispvm concurrent GUI calls"""
125- self .run_test ("dispvm- dom0-gui-concurrent" )
160+ self .run_test ("dom0-dispvm -gui-concurrent" )
126161
127- def test_020_dispvm_preload (self ):
162+ def test_020_vm_dispvm_preload (self ):
128163 """Latency of vm-dispvm (preload) calls"""
129- self .run_test ("dispvm-preload" )
164+ self .run_test ("vm- dispvm-preload" )
130165
131- def test_021_dispvm_preload_gui (self ):
166+ def test_021_vm_dispvm_preload_gui (self ):
132167 """Latency of vm-dispvm (preload) GUI calls"""
133- self .run_test ("dispvm-preload-gui" )
168+ self .run_test ("vm- dispvm-preload-gui" )
134169
135- def test_022_dispvm_preload_concurrent (self ):
170+ def test_022_vm_dispvm_preload_concurrent (self ):
136171 """Latency of vm-dispvm (preload) concurrent calls"""
137- self .run_test ("dispvm-preload-concurrent" )
172+ self .run_test ("vm- dispvm-preload-concurrent" )
138173
139- def test_023_dispvm_preload_gui_concurrent (self ):
174+ def test_023_vm_dispvm_preload_gui_concurrent (self ):
140175 """Latency of vm-dispvm (preload) concurrent GUI calls"""
141- self .run_test ("dispvm-preload-gui-concurrent" )
176+ self .run_test ("vm- dispvm-preload-gui-concurrent" )
142177
143- def test_026_dispvm_from_dom0_preload (self ):
178+ def test_026_dom0_dispvm_preload (self ):
144179 """Latency of dom0-dispvm (preload) calls"""
145- self .run_test ("dispvm-preload-dom0 " )
180+ self .run_test ("dom0- dispvm-preload" )
146181
147- def test_027_dispvm_from_dom0_preload_gui (self ):
182+ def test_027_dom0_dispvm_preload_gui (self ):
148183 """Latency of dom0-dispvm (preload) GUI calls"""
149- self .run_test ("dispvm-preload-dom0 -gui" )
184+ self .run_test ("dom0- dispvm-preload-gui" )
150185
151- def test_028_dispvm_from_dom0_preload_concurrent (self ):
186+ def test_028_dom0_dispvm_preload_concurrent (self ):
152187 """Latency of dom0-dispvm (preload) concurrent calls"""
153- self .run_test ("dispvm-preload-dom0 -concurrent" )
188+ self .run_test ("dom0- dispvm-preload-concurrent" )
154189
155- def test_029_dispvm_from_dom0_preload_gui_concurrent (self ):
190+ def test_029_dom0_dispvm_preload_gui_concurrent (self ):
156191 """Latency of dom0-dispvm (preload) concurrent GUI calls"""
157- self .run_test ("dispvm-preload-dom0 -gui-concurrent" )
192+ self .run_test ("dom0- dispvm-preload-gui-concurrent" )
158193
159- def test_400_dispvm_api (self ):
194+ def test_400_dom0_dispvm_api (self ):
160195 """Latency of dom0-dispvm API calls"""
161- self .run_test ("dispvm-api" )
196+ self .run_test ("dom0- dispvm-api" )
162197
163- def test_401_dispvm_gui_api (self ):
198+ def test_401_dom0_dispvm_gui_api (self ):
164199 """Latency of dom0-dispvm GUI API calls"""
165- self .run_test ("dispvm-gui-api" )
200+ self .run_test ("dom0- dispvm-gui-api" )
166201
167- def test_402_dispvm_concurrent_api (self ):
202+ def test_402_dom0_dispvm_concurrent_api (self ):
168203 """Latency of dom0-dispvm concurrent API calls"""
169- self .run_test ("dispvm-concurrent-api" )
204+ self .run_test ("dom0- dispvm-concurrent-api" )
170205
171- def test_403_dispvm_gui_concurrent_api (self ):
206+ def test_403_dom0_dispvm_gui_concurrent_api (self ):
172207 """Latency of dom0-dispvm concurrent GUI API calls"""
173- self .run_test ("dispvm-gui-concurrent-api" )
208+ self .run_test ("dom0- dispvm-gui-concurrent-api" )
174209
175- def test_404_dispvm_preload_more_api (self ):
176- """Latency of dom0-dispvm (preload more ) API calls"""
177- self .run_test ("dispvm-preload-more -api" )
210+ def test_404_dom0_dispvm_preload_less_less_api (self ):
211+ """Latency of dom0-dispvm (preload less less ) API calls"""
212+ self .run_test ("dom0- dispvm-preload-less-less -api" )
178213
179- def test_404_dispvm_preload_less_api (self ):
214+ def test_405_dom0_dispvm_preload_less_api (self ):
180215 """Latency of dom0-dispvm (preload less) API calls"""
181- self .run_test ("dispvm-preload-less-api" )
216+ self .run_test ("dom0- dispvm-preload-less-api" )
182217
183- def test_404_dispvm_preload_api (self ):
218+ def test_406_dom0_dispvm_preload_api (self ):
184219 """Latency of dom0-dispvm (preload) API calls"""
185- self .run_test ("dispvm-preload-api" )
220+ self .run_test ("dom0-dispvm-preload-api" )
221+
222+ def test_407_dom0_dispvm_preload_more_api (self ):
223+ """Latency of dom0-dispvm (preload more) API calls"""
224+ self .run_test ("dom0-dispvm-preload-more-api" )
225+
226+ def test_408_dom0_dispvm_preload_more_more_api (self ):
227+ """Latency of dom0-dispvm (preload more more) API calls"""
228+ self .run_test ("dom0-dispvm-preload-more-more-api" )
186229
187- def test_405_dispvm_preload_gui_api (self ):
230+ def test_409_dom0_dispvm_preload_gui_api (self ):
188231 """Latency of dom0-dispvm (preload) GUI API calls"""
189- self .run_test ("dispvm-preload-gui-api" )
232+ self .run_test ("dom0- dispvm-preload-gui-api" )
190233
191- def test_406_dispvm_preload_concurrent_api (self ):
234+ def test_410_dom0_dispvm_preload_concurrent_api (self ):
192235 """Latency of dom0-dispvm (preload) concurrent GUI API calls"""
193- self .run_test ("dispvm-preload-concurrent-api" )
236+ self .run_test ("dom0- dispvm-preload-concurrent-api" )
194237
195- def test_407_dispvm_preload_gui_concurrent_api (self ):
238+ def test_411_dom0_dispvm_preload_gui_concurrent_api (self ):
196239 """Latency of dom0-dispvm (preload) concurrent GUI API calls"""
197- self .run_test ("dispvm-preload-gui-concurrent-api" )
240+ self .run_test ("dom0- dispvm-preload-gui-concurrent-api" )
198241
199- def test_900_vm (self ):
242+ def test_800_vm_vm (self ):
200243 """Latency of vm-vm calls"""
201- self .run_test ("vm" )
244+ self .run_test ("vm-vm " )
202245
203- def test_901_vm_gui (self ):
246+ def test_801_vm_vm_gui (self ):
204247 """Latency of vm-vm GUI calls"""
205- self .run_test ("vm-gui" )
248+ self .run_test ("vm-vm- gui" )
206249
207- def test_902_vm_concurrent (self ):
250+ def test_802_vm_vm_concurrent (self ):
208251 """Latency of vm-vm concurrent calls"""
209- self .run_test ("vm-concurrent" )
252+ self .run_test ("vm-vm- concurrent" )
210253
211- def test_903_vm_gui_concurrent (self ):
254+ def test_803_vm_vm_gui_concurrent (self ):
212255 """Latency of vm-vm concurrent GUI calls"""
213- self .run_test ("vm-gui-concurrent" )
256+ self .run_test ("vm-vm- gui-concurrent" )
214257
215- def test_904_vm_api (self ):
258+ def test_804_dom0_vm_api (self ):
216259 """Latency of dom0-vm API calls"""
217- self .run_test ("vm-api" )
260+ self .run_test ("dom0- vm-api" )
218261
219- def test_905_vm_gui_api (self ):
262+ def test_805_dom0_vm_gui_api (self ):
220263 """Latency of dom0-vm GUI API calls"""
221- self .run_test ("vm-gui-api" )
264+ self .run_test ("dom0- vm-gui-api" )
222265
223- def test_906_vm_concurrent_api (self ):
266+ def test_806_dom0_vm_concurrent_api (self ):
224267 """Latency of dom0-vm concurrent API calls"""
225- self .run_test ("vm-concurrent-api" )
268+ self .run_test ("dom0- vm-concurrent-api" )
226269
227- def test_907_vm_gui_concurrent_api (self ):
270+ def test_807_dom0_vm_gui_concurrent_api (self ):
228271 """Latency of dom0-vm concurrent GUI API calls"""
229- self .run_test ("vm-gui-concurrent-api" )
272+ self .run_test ("dom0-vm-gui-concurrent-api" )
273+
274+ def test_900_reader (self ):
275+ """Render performance graphs."""
276+ self .run_reader (["--log-level=INFO" , "--no-show" ])
230277
231278
232279def create_testcases_for_templates ():
0 commit comments