Skip to content
Snippets Groups Projects
Commit 501a164e authored by Bob Lantz's avatar Bob Lantz Committed by Brian O'Connor
Browse files

Added --test option to boot and test a VM

parent 9e725cb2
No related branches found
No related tags found
No related merge requests found
......@@ -34,7 +34,7 @@
import re
from glob import glob
from subprocess import check_output, call, Popen
from tempfile import mkdtemp
from tempfile import mkdtemp, NamedTemporaryFile
from time import time, strftime, localtime
import argparse
from distutils.spawn import find_executable
......@@ -51,6 +51,8 @@
VMImageDir = os.environ[ 'HOME' ] + '/vm-images'
Prompt = '\$ ' # Shell prompt that pexpect will wait for
isoURLs = {
'precise32server':
'http://mirrors.kernel.org/ubuntu-releases/12.04/'
......@@ -141,8 +143,11 @@ def popen( cmd ):
def remove( fname ):
"rm -f fname"
return run( 'rm -f %s' % fname )
"Remove a file, ignoring errors"
try:
os.remove( fname )
except OSError:
pass
def findiso( flavor ):
......@@ -186,10 +191,10 @@ def detachNBD( nbd ):
srun( 'qemu-nbd -d ' + nbd )
def extractKernel( image, flavor ):
def extractKernel( image, flavor, imageDir=VMImageDir ):
"Extract kernel and initrd from base image"
kernel = path.join( VMImageDir, flavor + '-vmlinuz' )
initrd = path.join( VMImageDir, flavor + '-initrd' )
kernel = path.join( imageDir, flavor + '-vmlinuz' )
initrd = path.join( imageDir, flavor + '-initrd' )
if path.exists( kernel ) and ( stat( image )[ ST_MODE ] & 0777 ) == 0444:
# If kernel is there, then initrd should also be there
return kernel, initrd
......@@ -384,7 +389,7 @@ def installUbuntu( iso, image, logfilename='install.log' ):
raise Exception( 'Ubuntu installation returned error %d' %
vm.returncode )
log( '* UBUNTU INSTALLATION COMPLETED FOR', image )
log( '* Ubuntu installation completed in %.2f seconds ' % elapsed )
log( '* Ubuntu installation completed in %.2f seconds' % elapsed )
def boot( cow, kernel, initrd, logfile ):
......@@ -419,9 +424,8 @@ def boot( cow, kernel, initrd, logfile ):
return vm
def interact( vm ):
"Interact with vm, which is a pexpect object"
prompt = '\$ '
def login( vm ):
"Log in to vm (pexpect object)"
log( '* Waiting for login prompt' )
vm.expect( 'login: ' )
log( '* Logging in' )
......@@ -431,32 +435,19 @@ def interact( vm ):
log( '* Sending password' )
vm.sendline( 'mininet' )
log( '* Waiting for login...' )
vm.expect( prompt )
log( '* Sending hostname command' )
vm.sendline( 'hostname' )
log( '* Waiting for output' )
vm.expect( prompt )
log( '* Fetching Mininet VM install script' )
vm.sendline( 'wget '
'https://raw.github.com/mininet/mininet/master/util/vm/'
'install-mininet-vm.sh' )
vm.expect( prompt )
log( '* Running VM install script' )
vm.sendline( 'bash install-mininet-vm.sh' )
vm.expect ( 'password for mininet: ' )
vm.sendline( 'mininet' )
log( '* Waiting for script to complete... ' )
# Gigantic timeout for now ;-(
vm.expect( 'Done preparing Mininet', timeout=3600 )
log( '* Completed successfully' )
vm.expect( prompt )
log( '* Testing Mininet' )
def sanityTest( vm ):
"Run Mininet sanity test (pingall) in vm"
vm.sendline( 'sudo mn --test pingall' )
if vm.expect( [ ' 0% dropped', pexpect.TIMEOUT ], timeout=45 ) == 0:
log( '* Sanity check OK' )
else:
log( '* Sanity check FAILED' )
vm.expect( prompt )
def coreTest( vm, prompt=Prompt ):
"Run core tests (make test) in VM"
log( '* Making sure cgroups are mounted' )
vm.sendline( 'sudo service cgroup-lite restart' )
vm.expect( prompt )
......@@ -473,6 +464,35 @@ def interact( vm ):
log( '* Test', test, 'OK' )
else:
log( '* Test', test, 'FAILED' )
def interact( vm, prompt=Prompt ):
"Interact with vm, which is a pexpect object"
login( vm )
log( '* Waiting for login...' )
vm.expect( prompt )
log( '* Sending hostname command' )
vm.sendline( 'hostname' )
log( '* Waiting for output' )
vm.expect( prompt )
log( '* Fetching Mininet VM install script' )
vm.sendline( 'wget '
'https://raw.github.com/mininet/mininet/master/util/vm/'
'install-mininet-vm.sh' )
vm.expect( prompt )
log( '* Running VM install script' )
vm.sendline( 'bash install-mininet-vm.sh' )
vm.expect ( 'password for mininet: ' )
vm.sendline( 'mininet' )
log( '* Waiting for script to complete... ' )
# Gigantic timeout for now ;-(
vm.expect( 'Done preparing Mininet', timeout=3600 )
log( '* Completed successfully' )
vm.expect( prompt )
log( '* Testing Mininet' )
sanityTest( vm )
vm.expect( prompt )
coreTest( vm )
vm.expect( prompt )
log( '* Shutting down' )
vm.sendline( 'sync; sudo shutdown -h now' )
......@@ -649,6 +669,44 @@ def build( flavor='raring32server' ):
log( '* %s VM build DONE!!!!! :D' % flavor )
os.chdir( '..' )
def bootAndTest( image, tests=None ):
"""Boot and test VM
tests: list of tests (default: sanityTest, coreTest)"""
bootTestStart = time()
if tests is None:
tests = [ sanityTest, coreTest ]
basename = path.basename( image )
image = abspath( image )
tmpdir = mkdtemp( prefix='test-' + basename )
cow = path.join( tmpdir, image + '-cow.qcow2' )
log( '* Creating COW disk' )
run( 'qemu-img create -f qcow2 -b %s %s' % ( image, cow ) )
log( '* Extracting kernel and initrd' )
kernel, initrd = extractKernel( image, flavor=basename, imageDir=tmpdir )
if LogToConsole:
logfile = stdout
else:
logfile = NamedTemporaryFile( prefix=image, delete=False )
log( '* Logging VM output to', logfile.name )
vm = boot( cow=cow, kernel=kernel, initrd=initrd, logfile=logfile )
prompt = '\$ '
login( vm )
log( '* Waiting for VM boot and login' )
vm.expect( prompt )
for test in tests:
test( vm )
vm.expect( prompt )
log( '* Shutting down' )
vm.sendline( 'sudo shutdown -h now ' )
log( '* Waiting for shutdown' )
vm.wait()
log( '* Removing temporary dir', tmpdir )
srun( 'rm -rf ' + tmpdir )
elapsed = time() - bootTestStart
log( '* Boot and test completed in %.2f seconds' % elapsed )
def buildFlavorString():
"Return string listing valid build flavors"
return 'valid build flavors: %s' % ' '.join( sorted( isoURLs ) )
......@@ -671,6 +729,8 @@ def parseArgs():
help='save qcow2 image rather than deleting it' )
parser.add_argument( '-n', '--nokvm', action='store_true',
help="Don't use kvm - use tcg emulation instead" )
parser.add_argument( '-t', '--test', metavar='image', action='append',
help='Boot and test a VM image' )
parser.add_argument( 'flavor', nargs='*',
help='VM flavor(s) to build (e.g. raring32server)' )
args = parser.parse_args()
......@@ -694,7 +754,10 @@ def parseArgs():
# except Exception as e:
# log( '* BUILD FAILED with exception: ', e )
# exit( 1 )
if not ( args.depend or args.list or args.clean or args.flavor ):
for image in args.test:
bootAndTest( image )
if not ( args.depend or args.list or args.clean or args.flavor
or args.test ):
parser.print_help()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment