1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
3
# Copyright 2011 University of Southern California
4
# Licensed under the Apache License, Version 2.0 (the "License"); you may
5
# not use this file except in compliance with the License. You may obtain
6
# a copy of the License at
8
# http://www.apache.org/licenses/LICENSE-2.0
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
# License for the specific language governing permissions and limitations
22
from nova.compute import power_state
23
from nova import exception
24
from nova import flags
25
from nova.openstack.common import jsonutils
27
from nova.tests import fake_utils
29
from nova.virt.baremetal import dom
30
from nova.virt.baremetal import driver
36
# Same fake_domains is used by different classes,
37
# but different fake_file is used by different classes for unit test.
38
fake_domains = [{'status': 1, 'name': 'instance-00000001',
39
'memory_kb': 16777216, 'kernel_id': '1896115634',
40
'ramdisk_id': '', 'image_id': '1552326678',
41
'vcpus': 1, 'node_id': 6,
42
'mac_address': '02:16:3e:01:4e:c9',
43
'ip_address': '10.5.1.2'}]
46
class DomainReadWriteTestCase(test.TestCase):
49
super(DomainReadWriteTestCase, self).setUp()
50
self.flags(baremetal_driver='fake')
52
def test_read_domain_with_empty_list(self):
53
"""Read a file that contains no domains"""
55
self.mox.StubOutWithMock(__builtin__, 'open')
56
fake_file = StringIO.StringIO('[]')
57
open('/tftpboot/test_fake_dom_file', 'r').AndReturn(fake_file)
61
domains = dom.read_domains('/tftpboot/test_fake_dom_file')
63
self.assertEqual(domains, [])
65
def test_read_domain(self):
66
"""Read a file that contains at least one domain"""
67
fake_file = StringIO.StringIO('''[{"status": 1,
68
"image_id": "1552326678", "vcpus": 1, "node_id": 6,
69
"name": "instance-00000001", "memory_kb": 16777216,
70
"mac_address": "02:16:3e:01:4e:c9", "kernel_id": "1896115634",
71
"ramdisk_id": "", "ip_address": "10.5.1.2"}]''')
73
self.mox.StubOutWithMock(__builtin__, 'open')
74
open('/tftpboot/test_fake_dom_file', 'r').AndReturn(fake_file)
78
domains = dom.read_domains('/tftpboot/test_fake_dom_file')
80
self.assertEqual(domains, fake_domains)
82
def test_read_no_file(self):
83
"""Try to read when the file does not exist
85
This should through and IO exception"""
87
self.mox.StubOutWithMock(__builtin__, 'open')
88
open('/tftpboot/test_fake_dom_file',
89
'r').AndRaise(IOError(2, 'No such file or directory',
90
'/tftpboot/test_fake_dom_file'))
94
self.assertRaises(exception.NotFound, dom.read_domains,
95
'/tftpboot/test_fake_dom_file')
97
def assertJSONEquals(self, x, y):
98
"""Check if two json strings represent the equivalent Python object"""
99
self.assertEquals(jsonutils.loads(x), jsonutils.loads(y))
100
return jsonutils.loads(x) == jsonutils.loads(y)
102
def test_write_domain(self):
103
"""Write the domain to file"""
104
self.mox.StubOutWithMock(__builtin__, 'open')
105
mock_file = self.mox.CreateMock(file)
106
expected_json = '''[{"status": 1,
107
"image_id": "1552326678", "vcpus": 1, "node_id": 6,
108
"name": "instance-00000001", "memory_kb": 16777216,
109
"mac_address": "02:16:3e:01:4e:c9", "kernel_id": "1896115634",
110
"ramdisk_id": "", "ip_address": "10.5.1.2"}]'''
111
open('/tftpboot/test_fake_dom_file', 'w').AndReturn(mock_file)
113
# Check if the argument to file.write() represents the same
114
# Python object as expected_json
115
# We can't do an exact string comparison
116
# because of ordering and whitespace
117
mock_file.write(mox.Func(functools.partial(self.assertJSONEquals,
123
dom.write_domains('/tftpboot/test_fake_dom_file', fake_domains)
126
class BareMetalDomTestCase(test.TestCase):
129
super(BareMetalDomTestCase, self).setUp()
130
self.flags(baremetal_driver='fake')
131
# Stub out utils.execute
132
fake_utils.stub_out_utils_execute(self.stubs)
135
super(BareMetalDomTestCase, self).tearDown()
137
# Reset the singleton state
138
dom.BareMetalDom._instance = None
139
dom.BareMetalDom._is_init = False
141
def test_read_domain_only_once(self):
142
"""Confirm that the domain is read from a file only once,
143
even if the object is instantiated multiple times"""
144
self.mox.StubOutWithMock(dom, 'read_domains')
145
self.mox.StubOutWithMock(dom, 'write_domains')
147
dom.read_domains('/tftpboot/test_fake_dom_file').AndReturn([])
148
dom.write_domains('/tftpboot/test_fake_dom_file', [])
152
# Instantiate multiple instances
153
x = dom.BareMetalDom()
154
x = dom.BareMetalDom()
155
x = dom.BareMetalDom()
157
def test_init_no_domains(self):
159
# Create the mock objects
160
self.mox.StubOutWithMock(dom, 'read_domains')
161
self.mox.StubOutWithMock(dom, 'write_domains')
163
dom.read_domains('/tftpboot/test_fake_dom_file').AndReturn([])
164
dom.write_domains('/tftpboot/test_fake_dom_file', [])
169
bmdom = dom.BareMetalDom()
172
self.assertEqual(bmdom.fake_dom_nums, 0)
174
def test_init_remove_non_running_domain(self):
175
"""Check to see that all entries in the domain list are removed
176
except for the one that is in the running state"""
178
domains = [dict(node_id=1, name='i-00000001',
179
status=power_state.NOSTATE),
180
dict(node_id=2, name='i-00000002', status=power_state.RUNNING),
181
dict(node_id=3, name='i-00000003', status=power_state.PAUSED),
182
dict(node_id=5, name='i-00000004', status=power_state.SHUTDOWN),
183
dict(node_id=7, name='i-00000005', status=power_state.CRASHED),
184
dict(node_id=8, name='i-00000006', status=power_state.SUSPENDED),
185
dict(node_id=9, name='i-00000007', status=power_state.NOSTATE)]
187
# Create the mock objects
188
self.mox.StubOutWithMock(dom, 'read_domains')
189
self.mox.StubOutWithMock(dom, 'write_domains')
190
dom.read_domains('/tftpboot/test_fake_dom_file').AndReturn(domains)
191
dom.write_domains('/tftpboot/test_fake_dom_file', domains)
196
bmdom = dom.BareMetalDom()
198
self.assertEqual(bmdom.domains, [{'node_id': 2,
199
'name': 'i-00000002',
200
'status': power_state.RUNNING}])
201
self.assertEqual(bmdom.fake_dom_nums, 1)
203
def test_find_domain(self):
204
domain = {'status': 1, 'name': 'instance-00000001',
205
'memory_kb': 16777216, 'kernel_id': '1896115634',
206
'ramdisk_id': '', 'image_id': '1552326678',
207
'vcpus': 1, 'node_id': 6,
208
'mac_address': '02:16:3e:01:4e:c9',
209
'ip_address': '10.5.1.2'}
211
# Create the mock objects
212
self.mox.StubOutWithMock(dom, 'read_domains')
213
self.mox.StubOutWithMock(dom, 'write_domains')
216
dom.read_domains('/tftpboot/'
217
'test_fake_dom_file').AndReturn(fake_domains)
218
dom.write_domains('/tftpboot/test_fake_dom_file', fake_domains)
223
bmdom = dom.BareMetalDom()
226
self.assertEquals(bmdom.find_domain('instance-00000001'), domain)
229
class BareMetalTestCase(test.TestCase):
231
test_ip = '10.11.12.13'
232
test_instance = {'memory_kb': '1024000',
233
'basepath': '/some/path',
234
'bridge_name': 'br100',
235
'mac_address': '02:12:34:46:56:67',
237
'project_id': 'fake',
239
'image_ref': '123456',
240
'instance_type_id': '5'} # m1.small
243
super(BareMetalTestCase, self).setUp()
244
self.flags(baremetal_driver='fake')
245
fake_utils.stub_out_utils_execute(self.stubs)
247
def test_get_info(self):
248
# Create the mock objects
249
self.mox.StubOutWithMock(dom, 'read_domains')
250
self.mox.StubOutWithMock(dom, 'write_domains')
253
dom.read_domains('/tftpboot/'
254
'test_fake_dom_file').AndReturn(fake_domains)
255
dom.write_domains('/tftpboot/test_fake_dom_file', fake_domains)
260
conn = driver.BareMetalDriver(True)
261
# TODO(mikalstill): this is not a very good fake instance
262
info = conn.get_info({'name': 'instance-00000001'})
265
self.assertEquals(info['mem'], 16777216)
266
self.assertEquals(info['state'], 1)
267
self.assertEquals(info['num_cpu'], 1)
268
self.assertEquals(info['cpu_time'], 100)
269
self.assertEquals(info['max_mem'], 16777216)