~ubuntu-branches/ubuntu/raring/checkbox/raring-proposed

« back to all changes in this revision

Viewing changes to scripts/virtualization

  • Committer: Daniel Manrique
  • Date: 2013-02-08 18:32:10 UTC
  • mfrom: (1877.1.1 ubuntu-candidate)
  • Revision ID: roadmr@ubuntu.com-20130208183210-u5o8hkvvu5n1cxlo
Tags: 0.15.2
* New upstream release (LP: #1119529)
* Bumped revision number to 0.15.1 and restored previous trunk changelog.
* jobs/peripheral.txt.in: fixed string with repeated "add" (LP: #1102665) 
* scripts/graphics_stress_test: added missing import (LP: #1102812)
* scripts/rendercheck_test - added missing import for errno (LP: #1103343)
  jobs/rendercheck.txt.in - fixed command string to report the correct exit
  code to checkbox

* Converted kvm virtualization test to python3. Test will use parameters
  in config file in the event the system under test does not have internet
  access. Updated jobs/virtualization.txt.in

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python3
 
2
 
 
3
"""
 
4
Script to test virtualization functionality
 
5
 
 
6
Copyright (C) 2013 Canonical Ltd.
 
7
 
 
8
Authors
 
9
  Jeff Marcom <jeff.marcom@canonical.com>
 
10
 
 
11
This program is free software: you can redistribute it and/or modify
 
12
it under the terms of the GNU General Public License version 3,
 
13
as published by the Free Software Foundation.
 
14
 
 
15
This program is distributed in the hope that it will be useful,
 
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
GNU General Public License for more details.
 
19
 
 
20
You should have received a copy of the GNU General Public License
 
21
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
22
 
 
23
"""
 
24
 
 
25
from argparse import ArgumentParser
 
26
import configparser
 
27
import os
 
28
import logging
 
29
import lsb_release
 
30
import signal
 
31
from subprocess import Popen, PIPE
 
32
import sys
 
33
import tempfile
 
34
import time
 
35
import urllib.request
 
36
 
 
37
 
 
38
class XENTest(object):
 
39
    pass
 
40
 
 
41
 
 
42
class KVMTest(object):
 
43
 
 
44
    def __init__(self, image=None, timeout=500, debug_file="virt_debug"):
 
45
        self.image = image
 
46
        self.timeout = timeout
 
47
        self.debug_file = debug_file
 
48
 
 
49
    @classmethod
 
50
    def download_image(cls):
 
51
        """
 
52
        Downloads Cloud image for same release as host machine
 
53
        """
 
54
 
 
55
        # Check Ubuntu release info. Example {quantal, precise}
 
56
        release = lsb_release.get_lsb_information()["CODENAME"]
 
57
 
 
58
        # Construct URL
 
59
        cloud_url = "http://cloud-images.ubuntu.com"
 
60
        cloud_iso = release + "-server-cloudimg-i386-disk1.img"
 
61
        image_url = "/".join((
 
62
            cloud_url, release, "current", cloud_iso))
 
63
 
 
64
        logging.debug("Downloading {}, from {}".format(cloud_iso, cloud_url))
 
65
 
 
66
        # Attempt download
 
67
        try:
 
68
            resp = urllib.request.urlretrieve(image_url, cloud_iso)
 
69
        except urllib.error.HTTPError as exception:
 
70
            logging.error("Failed download {}: {}".format(image_url, exception))
 
71
            return False
 
72
 
 
73
        if not os.path.isfile(cloud_iso):
 
74
            return False
 
75
 
 
76
        return cloud_iso
 
77
 
 
78
    def boot_image(self, data_disk):
 
79
        """
 
80
        Attempts to boot the newly created qcow image using
 
81
        the config data defined in config.iso. Return instance
 
82
        of currently running virtual machine
 
83
        """
 
84
 
 
85
        logging.debug("Attempting boot for:{}".format(data_disk))
 
86
 
 
87
        # Set Arbitrary IP values
 
88
        netrange = "10.0.0.0/8"
 
89
        image_ip = "10.0.0.1"
 
90
        hostfwd = "tcp::2222-:22"
 
91
 
 
92
        params = \
 
93
        '''
 
94
        kvm -m {0} -net nic -net user,net={1},host={2},
 
95
        hostfwd={3} -drive file={4},if=virtio -display none -nographic
 
96
        '''.format(
 
97
            "256",
 
98
            netrange,
 
99
            image_ip,
 
100
            hostfwd,
 
101
            data_disk).replace("\n", "").replace("  ", "")
 
102
 
 
103
        logging.debug("Using params:{}".format(params))
 
104
 
 
105
        # Default file location for log file is in checkbox output directory
 
106
        checkbox_dir = os.getenv("CHECKBOX_DATA")
 
107
 
 
108
        if checkbox_dir != None:
 
109
            self.debug_file = os.path.join(checkbox_dir, self.debug_file)
 
110
 
 
111
        # Open VM STDERR/STDOUT log file for writing
 
112
        try:
 
113
            file = open(self.debug_file, 'w')
 
114
        except IOError:
 
115
            logging.error("Failed creating file:{}".format(self.debug_file))
 
116
            return False
 
117
 
 
118
        # Start Virtual machine
 
119
        self.process = Popen(params, stderr=file,
 
120
            stdout=file, universal_newlines=True, shell=True)
 
121
 
 
122
    def start(self):
 
123
        status = 1
 
124
        # Create temp directory:
 
125
        with tempfile.TemporaryDirectory("_kvm_test", 
 
126
        time.strftime("%b_%d_%Y_")) as temp_dir:
 
127
            
 
128
            os.chdir(temp_dir)
 
129
            if self.image is None:
 
130
                # Download cloud image
 
131
                self.image = self.download_image()
 
132
 
 
133
            if os.path.isfile(self.image):
 
134
 
 
135
                # Boot Virtual Machine
 
136
                instance = self.boot_image(self.image)
 
137
 
 
138
                if instance is not False:
 
139
                    time.sleep(self.timeout)
 
140
                    # Check to be sure VM boot was successful
 
141
                    if "END SSH HOST KEY KEYS" \
 
142
                    in open(self.debug_file, 'r').read():
 
143
                        print("Booted successfully", file=sys.stderr)
 
144
                        status = 0
 
145
                    else:
 
146
                        print("KVM instance failed to boot", file=sys.stderr)
 
147
                    self.process.terminate()
 
148
            else:
 
149
                print("Could not find: {}".format(self.image), file=sys.stderr)
 
150
 
 
151
        return status  
 
152
     
 
153
 
 
154
def test_kvm(args):
 
155
    print("Executing KVM Test", file=sys.stderr)
 
156
 
 
157
    DEFAULT_CFG = "/etc/checkbox.d/virtualization.cfg"
 
158
    image = ""
 
159
    timeout = ""
 
160
 
 
161
    config_file = DEFAULT_CFG
 
162
    config = configparser.SafeConfigParser()
 
163
 
 
164
    try:
 
165
        config.readfp(open(config_file))
 
166
        timeout = config.get("KVM", "timeout")
 
167
        image = config.get("KVM", "image") 
 
168
    except IOError:
 
169
        logging.warn("No config file found")
 
170
    except Exception as exception:
 
171
        logging.warn(exception)
 
172
 
 
173
    if image == "":
 
174
        image = args.image
 
175
    if timeout == "":
 
176
        timeout = args.timeout
 
177
 
 
178
    kvm_test = KVMTest(image, timeout)
 
179
    result = kvm_test.start()
 
180
 
 
181
    sys.exit(result)
 
182
 
 
183
 
 
184
def main():
 
185
 
 
186
    parser = ArgumentParser(description="Virtualization Test")
 
187
    subparsers = parser.add_subparsers()
 
188
 
 
189
    # Main cli options
 
190
    kvm_test_parser = subparsers.add_parser('kvm',
 
191
        help=("Run kvm virtualization test"))
 
192
 
 
193
    #xen_test_parser = subparsers.add_parser('xen',
 
194
    #    help=("Run xen virtualization test"))
 
195
 
 
196
    # Sub test options
 
197
    kvm_test_parser.add_argument('-i', '--image',
 
198
        type=str, default=None)
 
199
    kvm_test_parser.add_argument('-t', '--timeout',
 
200
        type=int, default=500)
 
201
    kvm_test_parser.add_argument('--debug',
 
202
        action="store_true")
 
203
    kvm_test_parser.set_defaults(func=test_kvm)
 
204
 
 
205
    args = parser.parse_args()
 
206
 
 
207
    if args.debug:
 
208
        logging.basicConfig(level=logging.DEBUG)
 
209
 
 
210
    args.func(args)
 
211
 
 
212
    
 
213
    
 
214
 
 
215
if __name__ == "__main__":
 
216
    main();