VirtualBox

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

Last change on this file since 78824 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 13.1 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# $Id: tdSerial1.py 76553 2019-01-01 01:45:53Z vboxsync $
4
5"""
6VirtualBox Validation Kit - Serial port testing #1.
7"""
8
9__copyright__ = \
10"""
11Copyright (C) 2018-2019 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: 76553 $"
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
54# Python 3 hacks:
55if sys.version_info[0] >= 3:
56 xrange = range; # pylint: disable=redefined-builtin,invalid-name
57
58
59class tdSerial1(vbox.TestDriver):
60 """
61 VBox serial port testing #1.
62 """
63
64 def __init__(self):
65 vbox.TestDriver.__init__(self);
66 self.asRsrcs = None;
67 self.oTestVmSet = self.oTestVmManager.selectSet(self.oTestVmManager.kfGrpStdSmoke);
68 self.asSerialModesDef = ['RawFile', 'Tcp', 'TcpServ', 'NamedPipe', 'NamedPipeServ', 'HostDev'];
69 self.asSerialModes = self.asSerialModesDef;
70 self.asSerialTestsDef = ['Write', 'ReadWrite'];
71 self.asSerialTests = self.asSerialTestsDef;
72 self.asUartsDef = ['16450', '16550A', '16750'];
73 self.asUarts = self.asUartsDef;
74 self.oLoopback = None;
75 self.sLocation = None;
76 self.fVerboseTest = False;
77
78 #
79 # Overridden methods.
80 #
81 def showUsage(self):
82 rc = vbox.TestDriver.showUsage(self);
83 reporter.log('');
84 reporter.log('tdSerial1 Options:');
85 reporter.log(' --serial-modes <m1[:m2[:]]');
86 reporter.log(' Default: %s' % (':'.join(self.asSerialModesDef)));
87 reporter.log(' --serial-tests <t1[:t2[:]]');
88 reporter.log(' Default: %s' % (':'.join(self.asSerialTestsDef)));
89 reporter.log(' --uarts <u1[:u2[:]]');
90 reporter.log(' Default: %s' % (':'.join(self.asUartsDef)));
91 reporter.log(' --verbose-test');
92 reporter.log(' Whether to enable verbose output when running the');
93 reporter.log(' test utility inside the VM');
94 return rc;
95
96 def parseOption(self, asArgs, iArg):
97 if asArgs[iArg] == '--serial-modes':
98 iArg += 1;
99 if iArg >= len(asArgs):
100 raise base.InvalidOption('The "--serial-modes" takes a colon separated list of serial port modes to test');
101 self.asSerialModes = asArgs[iArg].split(':');
102 for s in self.asSerialModes:
103 if s not in self.asSerialModesDef:
104 reporter.log('warning: The "--serial-modes" value "%s" is not a valid serial port mode.' % (s));
105 elif asArgs[iArg] == '--serial-tests':
106 iArg += 1;
107 if iArg >= len(asArgs):
108 raise base.InvalidOption('The "--serial-tests" takes a colon separated list of serial port tests');
109 self.asSerialTests = asArgs[iArg].split(':');
110 for s in self.asSerialTests:
111 if s not in self.asSerialTestsDef:
112 reporter.log('warning: The "--serial-tests" value "%s" is not a valid serial port test.' % (s));
113 elif asArgs[iArg] == '--aurts':
114 iArg += 1;
115 if iArg >= len(asArgs):
116 raise base.InvalidOption('The "--uarts" takes a colon separated list of uarts to test');
117 self.asUarts = asArgs[iArg].split(':');
118 for s in self.asUarts:
119 if s not in self.asUartsDef:
120 reporter.log('warning: The "--uarts" value "%s" is not a valid uart.' % (s));
121 elif asArgs[iArg] == '--verbose-test':
122 iArg += 1;
123 self.fVerboseTest = True;
124 else:
125 return vbox.TestDriver.parseOption(self, asArgs, iArg);
126
127 return iArg + 1;
128
129 def actionVerify(self):
130 if self.sVBoxValidationKitIso is None or not os.path.isfile(self.sVBoxValidationKitIso):
131 reporter.error('Cannot find the VBoxValidationKit.iso! (%s)'
132 'Please unzip a Validation Kit build in the current directory or in some parent one.'
133 % (self.sVBoxValidationKitIso,) );
134 return False;
135 return vbox.TestDriver.actionVerify(self);
136
137 def actionConfig(self):
138 # Make sure vboxapi has been imported so we can use the constants.
139 if not self.importVBoxApi():
140 return False;
141
142 assert self.sVBoxValidationKitIso is not None;
143 return self.oTestVmSet.actionConfig(self, sDvdImage = self.sVBoxValidationKitIso);
144
145 def actionExecute(self):
146 """
147 Execute the testcase.
148 """
149 return self.oTestVmSet.actionExecute(self, self.testOneVmConfig)
150
151
152 #
153 # Test execution helpers.
154 #
155
156 def _generateRawPortFilename(self, oTestDrv, oTestVm, sInfix, sSuffix):
157 """ Generates a raw port filename. """
158 random.seed();
159 sRandom = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(10));
160 return os.path.join(oTestDrv.sScratchPath, oTestVm.sVmName + sInfix + sRandom + sSuffix);
161
162 def setupSerialMode(self, oSession, oTestVm, sMode):
163 """
164 Sets up the serial mode.
165 """
166 fRc = True;
167 fServer = False;
168 sLocation = None;
169 ePortMode = vboxcon.PortMode_Disconnected;
170 if sMode == 'RawFile':
171 sLocation = self._generateRawPortFilename(self, oTestVm, '-com1-', '.out');
172 ePortMode = vboxcon.PortMode_RawFile;
173 elif sMode == 'Tcp':
174 sLocation = '127.0.0.1:1234';
175 self.oLoopback = loopback.SerialLoopback(loopback.g_ksLoopbackTcpServ, sLocation);
176 ePortMode = vboxcon.PortMode_TCP;
177 elif sMode == 'TcpServ':
178 fServer = True;
179 sLocation = '1234';
180 ePortMode = vboxcon.PortMode_TCP;
181 self.oLoopback = loopback.SerialLoopback(loopback.g_ksLoopbackTcpClient, '127.0.0.1:1234');
182 elif sMode == 'NamedPipe':
183 sLocation = self._generateRawPortFilename(self, oTestVm, '-com1-', '.out');
184 ePortMode = vboxcon.PortMode_HostPipe;
185 self.oLoopback = loopback.SerialLoopback(loopback.g_ksLoopbackNamedPipeServ, sLocation);
186 elif sMode == 'NamedPipeServ':
187 fServer = True;
188 sLocation = self._generateRawPortFilename(self, oTestVm, '-com1-', '.out');
189 ePortMode = vboxcon.PortMode_HostPipe;
190 self.oLoopback = loopback.SerialLoopback(loopback.g_ksLoopbackNamedPipeClient, sLocation);
191 elif sMode == 'HostDev':
192 sLocation = '/dev/ttyUSB0';
193 ePortMode = vboxcon.PortMode_HostDevice;
194 else:
195 reporter.log('warning, invalid mode %s given' % (sMode, ));
196 fRc = False;
197
198 if fRc:
199 fRc = oSession.changeSerialPortAttachment(0, ePortMode, sLocation, fServer);
200 if fRc and (sMode == 'TcpServ' or sMode == 'NamedPipeServ'):
201 self.sleep(2); # Fudge to allow the TCP server to get started.
202 fRc = self.oLoopback.connect();
203 if not fRc:
204 reporter.log('Failed to connect to %s' % (sLocation, ));
205 self.sLocation = sLocation;
206
207 return fRc;
208
209 def testWrite(self, oSession, oTxsSession, oTestVm, sMode):
210 """
211 Does a simple write test verifying the output.
212 """
213 _ = oSession;
214
215 reporter.testStart('Write');
216 tupCmdLine = ('SerialTest', '--tests', 'write', '--txbytes', '1048576');
217 if self.fVerboseTest:
218 tupCmdLine += ('--verbose',);
219 if oTestVm.isWindows():
220 tupCmdLine += ('--device', r'\\.\COM1',);
221 elif oTestVm.isLinux():
222 tupCmdLine += ('--device', r'/dev/ttyS0',);
223
224 fRc = self.txsRunTest(oTxsSession, 'SerialTest', 3600 * 1000, \
225 '${CDROM}/${OS/ARCH}/SerialTest${EXESUFF}', tupCmdLine);
226 if not fRc:
227 reporter.testFailure('Running serial test utility failed');
228 elif sMode == 'RawFile':
229 # Open serial port and verify
230 cLast = 0;
231 try:
232 oFile = open(self.sLocation, 'rb');
233 sFmt = '=I';
234 cBytes = 4;
235 for i in xrange(1048576 // 4):
236 _ = i;
237 sData = oFile.read(cBytes);
238 tupUnpacked = struct.unpack(sFmt, sData);
239 cLast = cLast + 1;
240 if tupUnpacked[0] != cLast:
241 reporter.testFailure('Corruption detected, expected counter value %s, got %s'
242 % (cLast + 1, tupUnpacked[0]));
243 break;
244 oFile.close();
245 except:
246 reporter.logXcpt();
247 reporter.testFailure('Verifying the written data failed');
248 reporter.testDone();
249 return fRc;
250
251 def testReadWrite(self, oSession, oTxsSession, oTestVm):
252 """
253 Does a simple write test verifying the output.
254 """
255 _ = oSession;
256
257 reporter.testStart('ReadWrite');
258 tupCmdLine = ('SerialTest', '--tests', 'readwrite', '--txbytes', '1048576');
259 if self.fVerboseTest:
260 tupCmdLine += ('--verbose',);
261 if oTestVm.isWindows():
262 tupCmdLine += ('--device', r'\\.\COM1',);
263 elif oTestVm.isLinux():
264 tupCmdLine += ('--device', r'/dev/ttyS0',);
265
266 fRc = self.txsRunTest(oTxsSession, 'SerialTest', 600 * 1000, \
267 '${CDROM}/${OS/ARCH}/SerialTest${EXESUFF}', tupCmdLine);
268 if not fRc:
269 reporter.testFailure('Running serial test utility failed');
270
271 reporter.testDone();
272 return fRc;
273
274 def isModeCompatibleWithTest(self, sMode, sTest):
275 """
276 Returns whether the given port mode and test combination is
277 supported for testing.
278 """
279 if sMode == 'RawFile' and sTest == 'ReadWrite':
280 return False;
281 elif sMode != 'RawFile' and sTest == 'Write':
282 return False;
283
284 return True;
285
286 def testOneVmConfig(self, oVM, oTestVm):
287 """
288 Runs the specified VM thru test #1.
289 """
290
291 for sUart in self.asUarts:
292 reporter.testStart(sUart);
293 # Reconfigure the VM
294 fRc = True;
295 oSession = self.openSession(oVM);
296 if oSession is not None:
297 fRc = oSession.enableSerialPort(0);
298
299 fRc = fRc and oSession.setExtraData("VBoxInternal/Devices/serial/0/Config/UartType", "string:" + sUart);
300 fRc = fRc and oSession.saveSettings();
301 fRc = oSession.close() and fRc;
302 oSession = None;
303 else:
304 fRc = False;
305
306 if fRc is True:
307 self.logVmInfo(oVM);
308 oSession, oTxsSession = self.startVmAndConnectToTxsViaTcp(oTestVm.sVmName, fCdWait = True);
309 if oSession is not None:
310 self.addTask(oTxsSession);
311
312 for sMode in self.asSerialModes:
313 reporter.testStart(sMode);
314 fRc = self.setupSerialMode(oSession, oTestVm, sMode);
315 if fRc:
316 for sTest in self.asSerialTests:
317 # Skip tests which don't work with the current mode.
318 if self.isModeCompatibleWithTest(sMode, sTest):
319 if sTest == 'Write':
320 fRc = self.testWrite(oSession, oTxsSession, oTestVm, sMode);
321 if sTest == 'ReadWrite':
322 fRc = self.testReadWrite(oSession, oTxsSession, oTestVm);
323 if self.oLoopback is not None:
324 self.oLoopback.shutdown();
325 self.oLoopback = None;
326
327 reporter.testDone();
328
329 self.removeTask(oTxsSession);
330 self.terminateVmBySession(oSession);
331 reporter.testDone();
332
333 return fRc;
334
335if __name__ == '__main__':
336 sys.exit(tdSerial1().main(sys.argv));
337
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