mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-06 07:33:01 +02:00
test: Refactor upgrade test
* Use new cleanup in infamy to ensure the boot order gets restored * Use new boot order in operational and use RPC to set boot order to remove all SSH commands.
This commit is contained in:
@@ -20,8 +20,6 @@ endif::topdoc[]
|
||||
. Wait for upgrade to finish
|
||||
. Verify boot order has changed and reboot
|
||||
. Verify that the partition is the booted
|
||||
. Restore boot order to original configured
|
||||
. Verify the boot order is the orignal configured
|
||||
|
||||
|
||||
<<<
|
||||
|
||||
@@ -25,30 +25,30 @@ PKGPATH = os.path.join(
|
||||
BUNDLEDIR,
|
||||
"package"
|
||||
)
|
||||
def get_boot_order(target):
|
||||
oper = target.get_dict("/system-state/software")
|
||||
return " ".join(oper["system-state"]["software"]["boot-order"])
|
||||
|
||||
class Uboot:
|
||||
def __init__(self, ssh):
|
||||
self.ssh=ssh
|
||||
def set_boot_order(target, order):
|
||||
target.call_dict("infix-system", {
|
||||
"set-boot-order": {
|
||||
"boot-order": order.split(" ")
|
||||
}
|
||||
})
|
||||
|
||||
def get_boot_order(self):
|
||||
order=self.ssh.runsh("sudo fw_printenv BOOT_ORDER").stdout.split("=")
|
||||
return order[1].strip()
|
||||
|
||||
def set_boot_order(self, order):
|
||||
return self.ssh.run(f"sudo fw_setenv BOOT_ORDER '{order}'".split()).returncode
|
||||
def cleanup(env, old_bootorder):
|
||||
print(f"Restore boot order to {old_bootorder}")
|
||||
target = env.attach("target", "mgmt", "netconf")
|
||||
set_boot_order(target, old_bootorder)
|
||||
target.reboot()
|
||||
if not wait_boot(target, env):
|
||||
test.fail()
|
||||
target = env.attach("target", "mgmt", "netconf")
|
||||
|
||||
class Grub:
|
||||
def __init__(self, ssh):
|
||||
self.ssh = ssh
|
||||
|
||||
def get_boot_order(self):
|
||||
lines=self.ssh.runsh("grub-editenv /mnt/aux/grub/grubenv list").stdout.split("\n")
|
||||
for line in lines:
|
||||
if "ORDER" in line:
|
||||
return line.split("=")[1].strip()
|
||||
|
||||
def set_boot_order(self, order):
|
||||
return self.ssh.run(f"sudo grub-editenv /mnt/aux/grub/grubenv set ORDER='{order}'".split()).returncode
|
||||
print("Verify the boot order is the orignal configured")
|
||||
order = get_boot_order(target)
|
||||
assert order == old_bootorder, f"Unexpected bootorder: {repr(order)}"
|
||||
|
||||
with infamy.Test() as test:
|
||||
with test.step("Set up topology and attach to target DUT"):
|
||||
@@ -65,20 +65,13 @@ with infamy.Test() as test:
|
||||
os.symlink(os.path.abspath(env.args.package), PKGPATH)
|
||||
|
||||
target = env.attach("target", "mgmt", "netconf")
|
||||
target_ssh = env.attach("target", "mgmt", "ssh")
|
||||
if target_ssh.run("test -e /sys/firmware/devicetree/base/chosen/u-boot,version".split()).returncode == 0:
|
||||
bootloader=Uboot(target_ssh)
|
||||
elif target_ssh.run("test -e /mnt/aux/grub/grubenv".split()).returncode == 0:
|
||||
bootloader=Grub(target_ssh)
|
||||
else:
|
||||
print("No supported bootloader found")
|
||||
test.skip()
|
||||
|
||||
old_bootorder=bootloader.get_boot_order()
|
||||
old_bootorder=get_boot_order(target)
|
||||
print(f"Initial bootorder: {repr(old_bootorder)}")
|
||||
|
||||
_, hport = env.ltop.xlate("host", "data")
|
||||
_, tport = env.ltop.xlate("target", "data")
|
||||
test.push_test_cleanup(lambda: cleanup(env, old_bootorder))
|
||||
|
||||
netns = infamy.IsolatedMacVlan(hport).start()
|
||||
netns.addip("192.168.0.1")
|
||||
@@ -130,7 +123,9 @@ with infamy.Test() as test:
|
||||
test.fail()
|
||||
|
||||
with test.step("Verify boot order has changed and reboot"):
|
||||
assert(old_bootorder != bootloader.get_boot_order())
|
||||
print(get_boot_order(target))
|
||||
print(old_bootorder)
|
||||
assert(old_bootorder != get_boot_order(target))
|
||||
target.reboot()
|
||||
|
||||
if not wait_boot(target, env):
|
||||
@@ -139,24 +134,10 @@ with infamy.Test() as test:
|
||||
|
||||
|
||||
with test.step("Verify that the partition is the booted"):
|
||||
should_boot=bootloader.get_boot_order().split()[0]
|
||||
should_boot=get_boot_order(target).split()[0]
|
||||
oper = target.get_dict("/system-state/software")
|
||||
booted = oper["system-state"]["software"]["booted"]
|
||||
print(f"Should boot: {should_boot}, booted: {booted}")
|
||||
assert(booted == should_boot)
|
||||
|
||||
with test.step("Restore boot order to original configured"):
|
||||
print(f"Restore boot order to {old_bootorder}")
|
||||
if bootloader.set_boot_order(old_bootorder) != 0:
|
||||
test.fail()
|
||||
target = env.attach("target", "mgmt", "netconf")
|
||||
target.reboot()
|
||||
if not wait_boot(target, env):
|
||||
test.fail()
|
||||
target = env.attach("target", "mgmt", "netconf")
|
||||
|
||||
with test.step("Verify the boot order is the orignal configured"):
|
||||
order = bootloader.get_boot_order()
|
||||
assert order == old_bootorder, f"Unexpected bootorder: {repr(order)}"
|
||||
|
||||
test.succeed()
|
||||
|
||||
@@ -2,32 +2,41 @@
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
|
||||
<!-- Title: 1x1 Pages: 1 -->
|
||||
<svg width="274pt" height="45pt"
|
||||
viewBox="0.00 0.00 274.02 45.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 41)">
|
||||
<title>1x1</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-41 270.02,-41 270.02,4 -4,4"/>
|
||||
<!-- Title: 1x2 Pages: 1 -->
|
||||
<svg width="424pt" height="55pt"
|
||||
viewBox="0.00 0.00 424.03 55.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 51)">
|
||||
<title>1x2</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-51 420.03,-51 420.03,4 -4,4"/>
|
||||
<!-- host -->
|
||||
<g id="node1" class="node">
|
||||
<title>host</title>
|
||||
<polygon fill="none" stroke="black" points="0,-0.5 0,-36.5 100,-36.5 100,-0.5 0,-0.5"/>
|
||||
<text text-anchor="middle" x="25" y="-14.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">host</text>
|
||||
<polyline fill="none" stroke="black" points="50,-0.5 50,-36.5 "/>
|
||||
<text text-anchor="middle" x="75" y="-14.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polygon fill="none" stroke="black" points="0,-0.5 0,-46.5 100,-46.5 100,-0.5 0,-0.5"/>
|
||||
<text text-anchor="middle" x="25" y="-19.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">host</text>
|
||||
<polyline fill="none" stroke="black" points="50,-0.5 50,-46.5 "/>
|
||||
<text text-anchor="middle" x="75" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="50,-23.5 100,-23.5 "/>
|
||||
<text text-anchor="middle" x="75" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data</text>
|
||||
</g>
|
||||
<!-- target -->
|
||||
<g id="node2" class="node">
|
||||
<title>target</title>
|
||||
<polygon fill="none" stroke="black" points="150.02,-0.5 150.02,-36.5 266.02,-36.5 266.02,-0.5 150.02,-0.5"/>
|
||||
<text text-anchor="middle" x="175.02" y="-14.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="200.02,-0.5 200.02,-36.5 "/>
|
||||
<text text-anchor="middle" x="233.02" y="-14.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">target</text>
|
||||
<polygon fill="none" stroke="black" points="300.03,-0.5 300.03,-46.5 416.03,-46.5 416.03,-0.5 300.03,-0.5"/>
|
||||
<text text-anchor="middle" x="325.03" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="300.03,-23.5 350.03,-23.5 "/>
|
||||
<text text-anchor="middle" x="325.03" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data</text>
|
||||
<polyline fill="none" stroke="black" points="350.03,-0.5 350.03,-46.5 "/>
|
||||
<text text-anchor="middle" x="383.03" y="-19.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">target</text>
|
||||
</g>
|
||||
<!-- host--target -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>host:mgmt--target:mgmt</title>
|
||||
<path fill="none" stroke="lightgrey" stroke-width="2" d="M100,-18.5C100,-18.5 150.02,-18.5 150.02,-18.5"/>
|
||||
<path fill="none" stroke="lightgrey" stroke-width="2" d="M100,-35.5C100,-35.5 300.03,-35.5 300.03,-35.5"/>
|
||||
</g>
|
||||
<!-- host--target -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>host:data--target:data</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M100,-11.5C100,-11.5 300.03,-11.5 300.03,-11.5"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 2.2 KiB |
@@ -302,6 +302,9 @@ class Device(Transport):
|
||||
|
||||
return self.put_datastore("running", data)
|
||||
|
||||
def call_dict(self, model, call):
|
||||
pass # Need implementation
|
||||
|
||||
def call_rpc(self, rpc):
|
||||
"""Actually send a POST to RESTCONF server"""
|
||||
url = f"{self.rpc_url}/{rpc}"
|
||||
|
||||
@@ -47,6 +47,10 @@ class Transport(ABC):
|
||||
"""Needed since libyang is too nice and removes the original offset"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def call_dict(self, module, call):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def call_action(self, xpath):
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user