Skip to content

Commit bfe2e64

Browse files
Alexandra Ghecencoalxiord
Alexandra Ghecenco
authored andcommitted
api: add integration tests for updates
* only covering PUT updates Signed-off-by: Alexandra Ghecenco <[email protected]>
1 parent 2cb10c9 commit bfe2e64

File tree

1 file changed

+195
-2
lines changed

1 file changed

+195
-2
lines changed

tests/functional/test_api.py

Lines changed: 195 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
"""
2-
Tests that ensure the corectness of the Firecracker API.
2+
Tests that ensure the correctness of the Firecracker API.
33
44
# TODO
55
66
- Add many more API tests!
77
"""
88

99
import pytest
10-
10+
import shutil
1111

1212
@pytest.mark.timeout(240)
1313
def test_api_happy_start(test_microvm_any, uhttp):
@@ -91,3 +91,196 @@ def test_api_happy_start(test_microvm_any, uhttp):
9191
)
9292
""" Issues a power-on command to the microvm. """
9393
assert(uhttp.is_good_response(response.status_code))
94+
95+
96+
def test_api_put_update_pre_boot(test_microvm_any, uhttp):
97+
""" Tests that PUT updates are allowed before the microvm boots. """
98+
99+
test_microvm = test_microvm_any
100+
101+
_setup_microvm(test_microvm, uhttp)
102+
103+
response = uhttp.put(
104+
test_microvm.boot_cfg_url,
105+
json={
106+
'boot_source_id': '1',
107+
'source_type': 'LocalImage',
108+
'local_image': {'kernel_image_path': 'foo.bar'}
109+
}
110+
)
111+
""" Updating the kernel with an invalid path is not allowed. """
112+
assert(not uhttp.is_good_response(response.status_code))
113+
114+
kernel_copy = test_microvm.slot.kernel_file + '.copy'
115+
# The copy will be cleaned up by the microvm fixture's teardown() function.
116+
shutil.copy(test_microvm.slot.kernel_file, kernel_copy)
117+
response = uhttp.put(
118+
test_microvm.boot_cfg_url,
119+
json={
120+
'boot_source_id': '1',
121+
'source_type': 'LocalImage',
122+
'local_image': {'kernel_image_path': kernel_copy}
123+
}
124+
)
125+
""" Updates the kernel. """
126+
assert(uhttp.is_good_response(response.status_code))
127+
128+
response = uhttp.put(
129+
test_microvm.blk_cfg_url + '/root',
130+
json={
131+
'drive_id': 'root',
132+
'path_on_host': 'foo.bar',
133+
'is_root_device': True,
134+
'permissions': 'ro',
135+
'state': 'Attached'
136+
}
137+
)
138+
""" Updating a block device with an invalid path is not allowed. """
139+
assert(not uhttp.is_good_response(response.status_code))
140+
141+
response = uhttp.put(
142+
test_microvm.blk_cfg_url + '/scratch',
143+
json={
144+
'drive_id': 'scratch',
145+
'path_on_host': test_microvm.slot.make_fsfile(name='scratch'),
146+
'is_root_device': True,
147+
'permissions': 'rw',
148+
'state': 'Attached'
149+
}
150+
)
151+
""" An update that would result in two root block devices is not allowed."""
152+
assert(not uhttp.is_good_response(response.status_code))
153+
154+
response = uhttp.put(
155+
test_microvm.blk_cfg_url + '/scratch',
156+
json={
157+
'drive_id': 'scratch',
158+
'path_on_host': test_microvm.slot.make_fsfile(name='scratch'),
159+
'is_root_device': False,
160+
'permissions': 'ro',
161+
'state': 'Attached'
162+
}
163+
)
164+
""" Updates a block device."""
165+
assert(uhttp.is_good_response(response.status_code))
166+
167+
response = uhttp.put(test_microvm.microvm_cfg_url, json={'vcpu_count': 2})
168+
""" Updates the vcpu count in the machine configuration.
169+
The machine configuration has a default value, so all PUTs are updates.
170+
"""
171+
assert(uhttp.is_good_response(response.status_code))
172+
173+
response = uhttp.put(
174+
test_microvm.net_cfg_url + '/1',
175+
json={
176+
'iface_id': '1',
177+
'host_dev_name': test_microvm.slot.make_tap(name='dummytap'),
178+
'guest_mac': '06:00:00:00:00:01',
179+
'state': 'Attached'
180+
}
181+
)
182+
""" Updates the network interface."""
183+
assert(uhttp.is_good_response(response.status_code))
184+
185+
186+
def test_api_put_update_post_boot(test_microvm_any, uhttp):
187+
""" Tests that PUT updates are rejected after the microvm boots. """
188+
189+
test_microvm = test_microvm_any
190+
191+
_setup_microvm(test_microvm, uhttp)
192+
193+
uhttp.put(
194+
test_microvm.actions_url + '/1',
195+
json={'action_id': '1', 'action_type': 'InstanceStart'}
196+
)
197+
198+
response = uhttp.put(
199+
test_microvm.boot_cfg_url,
200+
json={
201+
'boot_source_id': '1',
202+
'source_type': 'LocalImage',
203+
'local_image': {'kernel_image_path': test_microvm.slot.kernel_file}
204+
}
205+
)
206+
""" Kernel update is not allowed after boot. """
207+
assert(not uhttp.is_good_response(response.status_code))
208+
209+
""" TODO
210+
Uncomment this block after the block device update is implemented properly. Until then, the PUT triggers a rescan.
211+
"""
212+
# response = uhttp.put(
213+
# test_microvm.blk_cfg_url + '/scratch',
214+
# json={
215+
# 'drive_id': 'scratch',
216+
# 'path_on_host': test_microvm.slot.make_fsfile(name='scratch'),
217+
# 'is_root_device': False,
218+
# 'permissions': 'ro',
219+
# 'state': 'Attached'
220+
# }
221+
# )
222+
# """ Block device updates are not allowed via PUT after boot."""
223+
# assert(not uhttp.is_good_response(response.status_code))
224+
225+
response = uhttp.put(test_microvm.microvm_cfg_url, json={'vcpu_count': 2})
226+
""" Machine configuration update is not allowed after boot."""
227+
assert(not uhttp.is_good_response(response.status_code))
228+
229+
response = uhttp.put(
230+
test_microvm.net_cfg_url + '/1',
231+
json={
232+
'iface_id': '1',
233+
'host_dev_name': test_microvm.slot.make_tap(name='dummytap'),
234+
'guest_mac': '06:00:00:00:00:01',
235+
'state': 'Attached'
236+
}
237+
)
238+
""" Network interface update is not allowed after boot."""
239+
assert(not uhttp.is_good_response(response.status_code))
240+
241+
242+
def _setup_microvm(test_microvm_any, uhttp):
243+
""" Sets up a microvm with a kernel, 2 block devices and a network interface. """
244+
245+
test_microvm = test_microvm_any
246+
247+
uhttp.put(
248+
test_microvm.boot_cfg_url,
249+
json={
250+
'boot_source_id': '1',
251+
'source_type': 'LocalImage',
252+
'local_image': {'kernel_image_path': test_microvm.slot.kernel_file}
253+
}
254+
)
255+
256+
uhttp.put(
257+
test_microvm.blk_cfg_url + '/root',
258+
json={
259+
'drive_id': 'root',
260+
'path_on_host': test_microvm.slot.rootfs_file,
261+
'is_root_device': True,
262+
'permissions': 'ro',
263+
'state': 'Attached'
264+
}
265+
)
266+
267+
uhttp.put(
268+
test_microvm.blk_cfg_url + '/scratch',
269+
json={
270+
'drive_id': 'scratch',
271+
'path_on_host': test_microvm.slot.make_fsfile(name='scratch'),
272+
'is_root_device': False,
273+
'permissions': 'rw',
274+
'state': 'Attached'
275+
}
276+
)
277+
278+
uhttp.put(
279+
test_microvm.net_cfg_url + '/1',
280+
json={
281+
'iface_id': '1',
282+
'host_dev_name': test_microvm.slot.make_tap(),
283+
'guest_mac': '06:00:00:00:00:01',
284+
'state': 'Attached'
285+
}
286+
)

0 commit comments

Comments
 (0)