VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/tests/serial/tdSerial1.py@ 72081

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

ValidationKit/tests/serial: Add verbose flag to avoid flooding the log with error messages by default

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 12.0 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# $Id: tdSerial1.py 72029 2018-04-26 08:32:47Z vboxsync $
4
5"""
6VirtualBox Validation Kit - Serial port testing #1.
7"""
8
9__copyright__ = \
10"""
11Copyright (C) 2018 Oracle Corporation
12
13This file is part of VirtualBox Open Source Edition (OSE), as
14available from http://www.virtualbox.org. This file is free software;
15you can redistribute it and/or modify it under the terms of the GNU
16General Public License (GPL) as published by the Free Software
17Foundation, in version 2 as it comes in the "COPYING" file of the
18VirtualBox OSE distribution. VirtualBox OSE is distributed in the
19hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
20
21The contents of this file may alternatively be used under the terms
22of the Common Development and Distribution License Version 1.0
23(CDDL) only, as it comes in the "COPYING.CDDL" file of the
24VirtualBox OSE distribution, in which case the provisions of the
25CDDL are applicable instead of those of the GPL.
26
27You may elect to license modified versions of this file under the
28terms and conditions of either the GPL or the CDDL or both.
29"""
30__version__ = "$Revision: 72029 $"
31
32
33# Standard Python imports.
34import os;
35import random;
36import string;
37import struct;
38import sys;
39
40# Only the main script needs to modify the path.
41try: __file__
42except: __file__ = sys.argv[0];
43g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
44sys.path.append(g_ksValidationKitDir);
45
46# Validation Kit imports.
47from testdriver import base;
48from testdriver import reporter;
49from testdriver import vbox;
50from testdriver import vboxcon;
51
52import loopback;
53
54class tdSerial1(vbox.TestDriver):
55 """
56 VBox serial port testing #1.
57 """
58
59 def __init__(self):
60 vbox.TestDriver.__init__(self);
61 self.asRsrcs = None;
62 self.oTestVmSet = self.oTestVmManager.selectSet(self.oTestVmManager.kfGrpStdSmoke);
63 self.asSerialModesDef = ['RawFile', 'Tcp', 'TcpServ', 'NamedPipe', 'NamedPipeServ', 'HostDev'];
64 self.asSerialModes = self.asSerialModesDef;
65 self.asSerialTestsDef = ['Write', 'ReadWrite'];
66 self.asSerialTests = self.asSerialTestsDef;
67 self.oLoopback = None;
68 self.sLocation = None;
69 self.fVerboseTest = False;
70
71 #
72 # Overridden methods.
73 #
74 def showUsage(self):
75 rc = vbox.TestDriver.showUsage(self);
76 reporter.log('');
77 reporter.log('tdSerial1 Options:');
78 reporter.log(' --serial-modes <m1[:m2[:]]');
79 reporter.log(' Default: %s' % (':'.join(self.asSerialModesDef)));
80 reporter.log(' --serial-tests <t1[:t2[:]]');
81 reporter.log(' Default: %s' % (':'.join(self.asSerialTestsDef)));
82 reporter.log(' --verbose-test');
83 reporter.log(' Whether to enable verbose output when running the');
84 reporter.log(' test utility inside the VM');
85 return rc;
86
87 def parseOption(self, asArgs, iArg):
88 if asArgs[iArg] == '--serial-modes':
89 iArg += 1;
90 if iArg >= len(asArgs):
91 raise base.InvalidOption('The "--serial-modes" takes a colon separated list of serial port modes to test');
92 self.asSerialModes = asArgs[iArg].split(':');
93 for s in self.asSerialModes:
94 if s not in self.asSerialModesDef:
95 reporter.log('warning: The "--serial-modes" value "%s" is not a valid serial port mode.' % (s));
96 elif asArgs[iArg] == '--serial-tests':
97 iArg += 1;
98 if iArg >= len(asArgs):
99 raise base.InvalidOption('The "--serial-tests" takes a colon separated list of serial port tests');
100 self.asSerialTests = asArgs[iArg].split(':');
101 for s in self.asSerialTests:
102 if s not in self.asSerialTestsDef:
103 reporter.log('warning: The "--serial-tests" value "%s" is not a valid serial port test.' % (s));
104 elif asArgs[iArg] == '--verbose-test':
105 iArg += 1;
106 self.fVerboseTest = True;
107 else:
108 return vbox.TestDriver.parseOption(self, asArgs, iArg);
109
110 return iArg + 1;
111
112 def actionVerify(self):
113 if self.sVBoxValidationKitIso is None or not os.path.isfile(self.sVBoxValidationKitIso):
114 reporter.error('Cannot find the VBoxValidationKit.iso! (%s)'
115 'Please unzip a Validation Kit build in the current directory or in some parent one.'
116 % (self.sVBoxValidationKitIso,) );
117 return False;
118 return vbox.TestDriver.actionVerify(self);
119
120 def actionConfig(self):
121 # Make sure vboxapi has been imported so we can use the constants.
122 if not self.importVBoxApi():
123 return False;
124
125 assert self.sVBoxValidationKitIso is not None;
126 return self.oTestVmSet.actionConfig(self, sDvdImage = self.sVBoxValidationKitIso);
127
128 def actionExecute(self):
129 """
130 Execute the testcase.
131 """
132 return self.oTestVmSet.actionExecute(self, self.testOneVmConfig)
133
134
135 #
136 # Test execution helpers.
137 #
138
139 def _generateRawPortFilename(self, oTestDrv, oTestVm, sInfix, sSuffix):
140 """ Generates a raw port filename. """
141 random.seed();
142 sRandom = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(10));
143 return os.path.join(oTestDrv.sScratchPath, oTestVm.sVmName + sInfix + sRandom + sSuffix);
144
145 def setupSerialMode(self, oSession, oTestVm, sMode):
146 """
147 Sets up the serial mode.
148 """
149 fRc = True;
150 fServer = False;
151 sLocation = None;
152 ePortMode = vboxcon.PortMode_Disconnected;
153 if sMode == 'RawFile':
154 sLocation = self._generateRawPortFilename(self, oTestVm, '-com1-', '.out');
155 ePortMode = vboxcon.PortMode_RawFile;
156 elif sMode == 'Tcp':
157 sLocation = '127.0.0.1:1234';
158 self.oLoopback = loopback.SerialLoopback(loopback.g_ksLoopbackTcpServ, sLocation);
159 ePortMode = vboxcon.PortMode_TCP;
160 elif sMode == 'TcpServ':
161 fServer = True;
162 sLocation = '1234';
163 ePortMode = vboxcon.PortMode_TCP;
164 self.oLoopback = loopback.SerialLoopback(loopback.g_ksLoopbackTcpClient, '127.0.0.1:1234');
165 elif sMode == 'NamedPipe':
166 sLocation = self._generateRawPortFilename(self, oTestVm, '-com1-', '.out');
167 ePortMode = vboxcon.PortMode_HostPipe;
168 self.oLoopback = loopback.SerialLoopback(loopback.g_ksLoopbackNamedPipeServ, sLocation);
169 elif sMode == 'NamedPipeServ':
170 fServer = True;
171 sLocation = self._generateRawPortFilename(self, oTestVm, '-com1-', '.out');
172 ePortMode = vboxcon.PortMode_HostPipe;
173 self.oLoopback = loopback.SerialLoopback(loopback.g_ksLoopbackNamedPipeClient, sLocation);
174 elif sMode == 'HostDev':
175 sLocation = '/dev/ttyUSB0';
176 ePortMode = vboxcon.PortMode_HostDevice;
177 else:
178 reporter.log('warning, invalid mode %s given' % (sMode, ));
179 fRc = False;
180
181 if fRc:
182 fRc = oSession.changeSerialPortAttachment(0, ePortMode, sLocation, fServer);
183 if fRc and (sMode == 'TcpServ' or sMode == 'NamedPipeServ'):
184 self.sleep(2); # Fudge to allow the TCP server to get started.
185 fRc = self.oLoopback.connect();
186 if not fRc:
187 reporter.log('Failed to connect to %s' % (sLocation, ));
188 self.sLocation = sLocation;
189
190 return fRc;
191
192 def testWrite(self, oSession, oTxsSession, oTestVm, sMode):
193 """
194 Does a simple write test verifying the output.
195 """
196 _ = oSession;
197
198 reporter.testStart('Write');
199 tupCmdLine = ('SerialTest', '--tests', 'write', '--txbytes', '1048576',);
200 if self.fVerboseTest:
201 tupCmdLine += ('--verbose');
202 if oTestVm.isWindows():
203 tupCmdLine += ('--device', r'\\.\COM1',);
204 elif oTestVm.isLinux():
205 tupCmdLine += ('--device', r'/dev/ttyS0',);
206
207 fRc = self.txsRunTest(oTxsSession, 'SerialTest', 3600 * 1000, \
208 '${CDROM}/${OS/ARCH}/SerialTest${EXESUFF}', tupCmdLine);
209 if not fRc:
210 reporter.testFailure('Running serial test utility failed');
211 elif sMode == 'RawFile':
212 # Open serial port and verify
213 cLast = 0;
214 try:
215 oFile = open(self.sLocation, 'rb');
216 sFmt = '=I';
217 cBytes = 4;
218 for i in xrange(1048576 / 4):
219 _ = i;
220 sData = oFile.read(cBytes);
221 tupUnpacked = struct.unpack(sFmt, sData);
222 cLast = cLast + 1;
223 if tupUnpacked[0] != cLast:
224 reporter.testFailure('Corruption detected, expected counter value %s, got %s'
225 % (cLast + 1, tupUnpacked[0]));
226 break;
227 oFile.close();
228 except:
229 reporter.logXcpt();
230 reporter.testFailure('Verifying the written data failed');
231 reporter.testDone();
232 return fRc;
233
234 def testReadWrite(self, oSession, oTxsSession, oTestVm):
235 """
236 Does a simple write test verifying the output.
237 """
238 _ = oSession;
239
240 reporter.testStart('ReadWrite');
241 tupCmdLine = ('SerialTest', '--tests', 'readwrite', '--txbytes', '1048576');
242 if self.fVerboseTest:
243 tupCmdLine += ('--verbose');
244 if oTestVm.isWindows():
245 tupCmdLine += ('--device', r'\\.\COM1',);
246 elif oTestVm.isLinux():
247 tupCmdLine += ('--device', r'/dev/ttyS0',);
248
249 fRc = self.txsRunTest(oTxsSession, 'SerialTest', 600 * 1000, \
250 '${CDROM}/${OS/ARCH}/SerialTest${EXESUFF}', tupCmdLine);
251 if not fRc:
252 reporter.testFailure('Running serial test utility failed');
253
254 reporter.testDone();
255 return fRc;
256
257 def isModeCompatibleWithTest(self, sMode, sTest):
258 """
259 Returns whether the given port mode and test combination is
260 supported for testing.
261 """
262 if sMode == 'RawFile' and sTest == 'ReadWrite':
263 return False;
264 elif sMode != 'RawFile' and sTest == 'Write':
265 return False;
266
267 return True;
268
269 def testOneVmConfig(self, oVM, oTestVm):
270 """
271 Runs the specified VM thru test #1.
272 """
273
274 # Reconfigure the VM
275 fRc = True;
276 oSession = self.openSession(oVM);
277 if oSession is not None:
278 fRc = oSession.enableSerialPort(0);
279
280 fRc = fRc and oSession.saveSettings();
281 fRc = oSession.close() and fRc;
282 oSession = None;
283 else:
284 fRc = False;
285
286 if fRc is True:
287 self.logVmInfo(oVM);
288 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(oTestVm.sVmName, fCdWait = True);
289 if oSession is not None:
290 self.addTask(oTxsSession);
291
292 for sMode in self.asSerialModes:
293 reporter.testStart(sMode);
294 fRc = self.setupSerialMode(oSession, oTestVm, sMode);
295 if fRc:
296 for sTest in self.asSerialTests:
297 # Skip tests which don't work with the current mode.
298 if self.isModeCompatibleWithTest(sMode, sTest):
299 if sTest == 'Write':
300 fRc = self.testWrite(oSession, oTxsSession, oTestVm, sMode);
301 if sTest == 'ReadWrite':
302 fRc = self.testReadWrite(oSession, oTxsSession, oTestVm);
303 if self.oLoopback is not None:
304 self.oLoopback.shutdown();
305 self.oLoopback = None;
306
307 reporter.testDone();
308
309 self.removeTask(oTxsSession);
310 self.terminateVmBySession(oSession);
311 return fRc;
312
313if __name__ == '__main__':
314 sys.exit(tdSerial1().main(sys.argv));
315
Note: See TracBrowser for help on using the repository browser.

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