VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/tests/audio/tdGuestHostTimings.py@ 69450

Last change on this file since 69450 was 69450, checked in by vboxsync, 7 years ago

test/audio: updates

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.7 KB
Line 
1# -*- coding: utf-8 -*-
2# $Id: tdGuestHostTimings.py 69450 2017-10-27 17:04:05Z vboxsync $
3
4"""
5????????
6"""
7
8__copyright__ = \
9"""
10Copyright (C) 2012-2017 Oracle Corporation
11
12This file is part of VirtualBox Open Source Edition (OSE), as
13available from http://www.virtualbox.org. This file is free software;
14you can redistribute it and/or modify it under the terms of the GNU
15General Public License (GPL) as published by the Free Software
16Foundation, in version 2 as it comes in the "COPYING" file of the
17VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19
20The contents of this file may alternatively be used under the terms
21of the Common Development and Distribution License Version 1.0
22(CDDL) only, as it comes in the "COPYING.CDDL" file of the
23VirtualBox OSE distribution, in which case the provisions of the
24CDDL are applicable instead of those of the GPL.
25
26You may elect to license modified versions of this file under the
27terms and conditions of either the GPL or the CDDL or both.
28"""
29__version__ = "$Revision: 69450 $"
30
31
32import os
33import sys
34import time
35import subprocess
36import re
37import time
38
39# Only the main script needs to modify the path.
40try: __file__
41except: __file__ = sys.argv[0];
42g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
43sys.path.append(g_ksValidationKitDir);
44
45# Validation Kit imports.
46from testdriver import reporter
47from testdriver import base
48from testdriver import vbox
49from testdriver import vboxcon
50from testdriver import vboxtestvms
51
52class tdGuestHostTimings(vbox.TestDriver): # pylint: disable=R0902
53
54 def __init__(self):
55 vbox.TestDriver.__init__(self);
56 self.sSessionTypeDef = 'gui';
57
58 self.oTestVmSet = self.oTestVmManager.getStandardVmSet('nat')
59
60 # Use the command line "--test-vms mw7x64 execute" to run the only "mw7x64" VM
61 oTestVm = vboxtestvms.TestVm(self.oTestVmSet, 'mw7x64', sHd = 'mw7x64.vdi',
62 sKind = 'Windows7', acCpusSup = range(1, 2), fIoApic = True, sFirmwareType = 'bios',
63 asParavirtModesSup = ['hyperv'], asVirtModesSup = ['hwvirt-np'], sHddControllerType = 'SATA Controller');
64
65 self.oTestVmSet.aoTestVms.append(oTestVm);
66
67 self.sVMname = None
68
69 def showUsage(self):
70 rc = vbox.TestDriver.showUsage(self);
71 reporter.log('');
72 reporter.log('tdGuestHostTimings Options:');
73 reporter.log(' --runningvmname <vmname>');
74 return rc;
75
76 def parseOption(self, asArgs, iArg): # pylint: disable=R0912,R0915
77 if asArgs[iArg] == '--runningvmname':
78 iArg += 1
79 if iArg >= len(asArgs):
80 raise base.InvalidOption('The "----runningvmname" needs VM name')
81
82 self.sVMname = asArgs[iArg]
83 else:
84 return vbox.TestDriver.parseOption(self, asArgs, iArg)
85 return iArg + 1
86
87 def actionConfig(self):
88 return True
89
90 def actionExecute(self):
91 #self.sTempPathHost = os.environ.get("IPRT_TMPDIR")
92 self.sTempPathHost = os.path.normpath(os.environ.get("TEMP") + "/VBoxAudioValKit")
93
94 if self.sVMname is None:
95 return self.oTestVmSet.actionExecute(self, self.testOneVmConfig)
96 else:
97 return self.actionExecuteOnRunnigVM()
98
99 def doTest(self, oSession):
100 oConsole = oSession.console
101 oGuest = oConsole.guest
102
103 sOSTypeId = oGuest.OSTypeId.lower()
104 if sOSTypeId.find("win") == -1 :
105 reporter.log("Only Windows guests are currently supported")
106 reporter.testDone()
107 return True
108
109 oGuestSession = oGuest.createSession("Administrator", "password", "", "Audio Validation Kit")
110 guestSessionWaitResult = oGuestSession.waitFor(self.oVBoxMgr.constants.GuestSessionWaitResult_Start, 2000)
111 reporter.log("guestSessionWaitResult = %d" % guestSessionWaitResult)
112
113 for duration in range(3, 6):
114 reporter.testStart("Checking for duration of " + str(duration) + " seconds")
115 sPathToPlayer = "D:\\win\\" + ("amd64" if (sOSTypeId.find('_64') >= 0) else "x86") + "\\ntPlayToneWaveX.exe"
116 oProcess = oGuestSession.processCreate(sPathToPlayer, ["xxx0", "--total-duration-in-secs", str(duration)], [], [], 0)
117 processWaitResult = oProcess.waitFor(self.oVBoxMgr.constants.ProcessWaitForFlag_Start, 1000)
118 reporter.log("Started: pid %d, waitResult %d" % (oProcess.PID, processWaitResult))
119
120 processWaitResult = oProcess.waitFor(self.oVBoxMgr.constants.ProcessWaitForFlag_Terminate, 2 * duration * 1000)
121 reporter.log("Terminated: pid %d, waitResult %d" % (oProcess.PID, processWaitResult))
122 time.sleep(1) # Give audio backend sometime to save a stream to .wav file
123
124 absFileName = self.seekLatestAudioFileName(oGuestSession, duration)
125
126 if absFileName is None:
127 reporter.testFailure("Unable to find audio file")
128 continue
129
130 reporter.log("Checking audio file '" + absFileName + "'")
131
132 diff = self.checkGuestHostTimings(absFileName + ".timing")
133 if diff is not None:
134 if diff > 0.0: # Guest sends data quicker than a host can play
135 if diff > 0.01: # 1% is probably good threshold here
136 reporter.testFailure("Guest sends audio buffers too quickly")
137 else:
138 diff = -diff; # Much worse case: guest sends data very slow, host feels starvation
139 if diff > 0.005: # 0.5% is probably good threshold here
140 reporter.testFailure("Guest sends audio buffers too slowly")
141
142 reporter.testDone()
143 else:
144 reporter.testFailure("Unable to parse a file with timings")
145
146 oGuestSession.close()
147
148 del oGuest
149 del oConsole
150
151 return True
152
153 def testOneVmConfig(self, oVM, oTestVm):
154 #self.logVmInfo(oVM)
155 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(oTestVm.sVmName,
156 fCdWait = True,
157 cMsTimeout = 60 * 1000)
158 if oSession is not None and oTxsSession is not None:
159 # Wait until guest reported success
160 reporter.log('Guest started. Connection to TXS service established.')
161 self.doTest(oSessionWrapper.o)
162
163 return True
164
165 def actionExecuteOnRunnigVM(self):
166 if not self.importVBoxApi():
167 return False;
168
169 oVirtualBox = self.oVBoxMgr.getVirtualBox()
170 oMachine = oVirtualBox.findMachine(self.sVMname)
171
172 if oMachine == None:
173 reporter.log("Machine '%s' is unknown" % (oMachine.name))
174 return False
175
176 if oMachine.state != self.oVBoxMgr.constants.MachineState_Running:
177 reporter.log("Machine '%s' is not Running" % (oMachine.name))
178 return False
179
180 oSession = self.oVBoxMgr.mgr.getSessionObject(oVirtualBox)
181 oMachine.lockMachine(oSession, self.oVBoxMgr.constants.LockType_Shared)
182
183 self.doTest(oSession);
184
185 oSession.unlockMachine()
186
187 del oSession
188 del oMachine
189 del oVirtualBox
190 return True
191
192 def seekLatestAudioFileName(self, guestSession, duration):
193
194 listOfFiles = os.listdir(self.sTempPathHost)
195 # Assuming that .wav files are named like 2016-11-15T12_08_27.669573100Z.wav by VBOX audio backend
196 # So that sorting by name = sorting by creation date
197 listOfFiles.sort(reverse = True)
198
199 for fileName in listOfFiles:
200 if not fileName.endswith(".wav"):
201 continue
202
203 absFileName = os.path.join(self.sTempPathHost, fileName)
204
205 # Ignore too small wav files (usually uncompleted audio streams)
206 statInfo = os.stat(absFileName)
207 if statInfo.st_size > 100:
208 return absFileName
209
210 return
211
212 def checkGuestHostTimings(self, absFileName):
213 with open(absFileName) as f:
214 for line_terminated in f:
215 line = line_terminated.rstrip('\n')
216
217 reporter.log("Last line is: " + line)
218 matchObj = re.match( r'(\d+) (\d+)', line, re.I)
219 if matchObj:
220 hostTime = int(matchObj.group(1))
221 guestTime = int(matchObj.group(2))
222
223 diff = float(guestTime - hostTime) / hostTime
224 return diff
225
226 return
227
228if __name__ == '__main__':
229 sys.exit(tdGuestHostTimings().main(sys.argv));
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette