[1/1] support/testing: add lxc test
diff mbox series

Message ID 20191107164804.30773-1-patrick.havelange@essensium.com
State Superseded
Headers show
Series
  • [1/1] support/testing: add lxc test
Related show

Commit Message

Patrick Havelange Nov. 7, 2019, 4:48 p.m. UTC
The test starts a simple container with an iperf3 server.
The container is using the tini init system, with a shared rootfs.
An iperf3 client is started from the host to check that the container
is really up and running.

Signed-off-by: Patrick Havelange <patrick.havelange@essensium.com>
---
 .gitlab-ci.yml                                |  1 +
 support/testing/tests/package/test_lxc.py     | 58 +++++++++++++++++++
 .../tests/package/test_lxc/kernel_config_frag | 20 +++++++
 .../test_lxc_rootfs_overlay/usr/bin/iperf3.sh |  2 +
 .../usr/share/lxc/config/minimal-iperf3.conf  |  4 ++
 .../usr/share/lxc/config/minimal.conf         |  6 ++
 6 files changed, 91 insertions(+)
 create mode 100644 support/testing/tests/package/test_lxc.py
 create mode 100644 support/testing/tests/package/test_lxc/kernel_config_frag
 create mode 100755 support/testing/tests/package/test_lxc/test_lxc_rootfs_overlay/usr/bin/iperf3.sh
 create mode 100644 support/testing/tests/package/test_lxc/test_lxc_rootfs_overlay/usr/share/lxc/config/minimal-iperf3.conf
 create mode 100644 support/testing/tests/package/test_lxc/test_lxc_rootfs_overlay/usr/share/lxc/config/minimal.conf

Comments

Thomas Petazzoni Nov. 9, 2019, 2:05 p.m. UTC | #1
Hello Patrick,

On Thu,  7 Nov 2019 17:48:04 +0100
Patrick Havelange <patrick.havelange@essensium.com> wrote:

> The test starts a simple container with an iperf3 server.
> The container is using the tini init system, with a shared rootfs.
> An iperf3 client is started from the host to check that the container
> is really up and running.
> 
> Signed-off-by: Patrick Havelange <patrick.havelange@essensium.com>

Thanks for your contribution. I don't have a lot of very definitive
feedback, more some general thoughts.

First of all, what was the idea behind the use of iperf3 ? Is it just a
mean to make sure that both the container and host can communicate, and
that the container runs fine ?

Another question is about the shared rootfs situation: if I understand
correctly, the container runs with the same rootfs as the host.
Recently, Carlos Santos (in Cc), submitted a patch "package/test-vm: a
virtual machine image to  test libvirt", which builds a separate rootfs
image to run as a VM using libvirt. Shouldn't we standardize a bit how
the test cases will test things such as lxc/libvirt, and try to use
more or less the same strategy/logic to build the image executed inside
the container or VM ?

Note: this comment is really to open up the discussion on this topic.
Perhaps we will decide that what you did is good enough, and can
possibly be improved later.

> +    def run_ok(self, cmd):
> +        full_cmd = "sh -c '{}'".format(cmd)

Why is running through "sh -c" necessary ?

> +        out, exit_code = self.emulator.run(full_cmd, 120)
> +        self.assertEqual(exit_code, 0)

This seems like a useful helper method, perhaps we should have it in
the emulator class, and make use of it in other tests ?

Thanks!

Thomas
Arnout Vandecappelle Nov. 17, 2019, 7:40 p.m. UTC | #2
On 09/11/2019 15:05, Thomas Petazzoni wrote:
> Hello Patrick,
> 
> On Thu,  7 Nov 2019 17:48:04 +0100
> Patrick Havelange <patrick.havelange@essensium.com> wrote:
> 
>> The test starts a simple container with an iperf3 server.
>> The container is using the tini init system, with a shared rootfs.
>> An iperf3 client is started from the host to check that the container
>> is really up and running.
>>
>> Signed-off-by: Patrick Havelange <patrick.havelange@essensium.com>
> 
> Thanks for your contribution. I don't have a lot of very definitive
> feedback, more some general thoughts.
> 
> First of all, what was the idea behind the use of iperf3 ? Is it just a
> mean to make sure that both the container and host can communicate, and
> that the container runs fine ?

 Indeed. The container running is a bit limited for a test. Having network
access to it is a way to get a bit more confidence that it is really functional.

 ssh would be another option to test the network access, but is more complicated.

 nc also sounds like an obvious alternative, but that turns out to be
surprisingly difficult to set up correctly (in particular, reliably detecting
failure and not just timing out).

 That's why Patrick choose iperf, because it is really trivial.


> Another question is about the shared rootfs situation: if I understand
> correctly, the container runs with the same rootfs as the host.
> Recently, Carlos Santos (in Cc), submitted a patch "package/test-vm: a
> virtual machine image to  test libvirt", which builds a separate rootfs
> image to run as a VM using libvirt. Shouldn't we standardize a bit how
> the test cases will test things such as lxc/libvirt, and try to use
> more or less the same strategy/logic to build the image executed inside
> the container or VM ?

 The idea would be to add several lxc tests, for the different use cases. One of
the use cases is a shared rootfs, another is a separate rootfs. test-vm could be
used for the second case. Another useful case will be with systemd inside and
outisde the container and being sure that they can talk to each other properly.


> Note: this comment is really to open up the discussion on this topic.
> Perhaps we will decide that what you did is good enough, and can
> possibly be improved later.
> 
>> +    def run_ok(self, cmd):
>> +        full_cmd = "sh -c '{}'".format(cmd)
> 
> Why is running through "sh -c" necessary ?

 Good question. Probably a leftover from when some commands were using redirection?


>> +        out, exit_code = self.emulator.run(full_cmd, 120)
>> +        self.assertEqual(exit_code, 0)
> 
> This seems like a useful helper method, perhaps we should have it in
> the emulator class, and make use of it in other tests ?

 Indeed, that could be useful.

 But then it should probably be called assertRunOk, similar to assertEqual. And
that again requires a noqa marking :-(

 Regards,
 Arnout

Patch
diff mbox series

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 1d71257a20..9ef93130a1 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -410,6 +410,7 @@  tests.package.test_luasocket.TestLuajitLuaSocket: { extends: .runtime_test }
 tests.package.test_luasyslog.TestLuaLuasyslog: { extends: .runtime_test }
 tests.package.test_luasyslog.TestLuajitLuasyslog: { extends: .runtime_test }
 tests.package.test_luvi.TestLuvi: { extends: .runtime_test }
+tests.package.test_lxc.TestLxc: { extends: .runtime_test }
 tests.package.test_lzlib.TestLuaLzlib: { extends: .runtime_test }
 tests.package.test_openjdk.TestOpenJdk: { extends: .runtime_test }
 tests.package.test_perl.TestPerl: { extends: .runtime_test }
diff --git a/support/testing/tests/package/test_lxc.py b/support/testing/tests/package/test_lxc.py
new file mode 100644
index 0000000000..348703ada6
--- /dev/null
+++ b/support/testing/tests/package/test_lxc.py
@@ -0,0 +1,58 @@ 
+import os
+
+import infra.basetest
+import pexpect
+
+class TestLxc(infra.basetest.BRTest):
+    config = \
+            """
+            BR2_arm=y
+            BR2_TOOLCHAIN_EXTERNAL=y
+            BR2_LINUX_KERNEL=y
+            BR2_LINUX_KERNEL_CUSTOM_VERSION=y
+            BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="4.19.79"
+            BR2_LINUX_KERNEL_DEFCONFIG="vexpress"
+            BR2_LINUX_KERNEL_DTS_SUPPORT=y
+            BR2_LINUX_KERNEL_INTREE_DTS_NAME="vexpress-v2p-ca9"
+            BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="{}"
+            BR2_TARGET_GENERIC_GETTY_PORT="ttyAMA0"
+            BR2_INIT_SYSTEMD=y
+            BR2_PACKAGE_LXC=y
+            BR2_PACKAGE_TINI=y
+            BR2_PACKAGE_IPERF3=y
+            BR2_ROOTFS_OVERLAY="{}"
+            BR2_TARGET_ROOTFS_CPIO=y
+            """.format(
+            infra.filepath("tests/package/test_lxc/kernel_config_frag"),
+            infra.filepath("tests/package/test_lxc/test_lxc_rootfs_overlay"))
+
+    def run_ok(self, cmd):
+        full_cmd = "sh -c '{}'".format(cmd)
+        out, exit_code = self.emulator.run(full_cmd, 120)
+        self.assertEqual(exit_code, 0)
+
+    def wait_boot(self):
+        #the complete boot with systemd takes more time than what the default multipler permits
+        self.emulator.timeout_multiplier *= 10
+        self.emulator.login()
+
+    def setup_run_test_container(self):
+        self.run_ok("lxc-create -n lxc_iperf3 -t none -f /usr/share/lxc/config/minimal-iperf3.conf")
+        self.run_ok("lxc-start -l trace -n lxc_iperf3 -o /tmp/lxc.log -L /tmp/lxc.console.log")
+        #need to wait for the container to be fully started
+        self.run_ok("sleep 2")
+        self.run_ok("iperf3 -c 192.168.1.2 -t 2")
+        #if the test fails, just cat /tmp/*.log
+
+    def test_run(self):
+        cpio_file = os.path.join(self.builddir, "images", "rootfs.cpio")
+        kernel_file = os.path.join(self.builddir, "images", "zImage")
+        dtb_file = os.path.join(self.builddir, "images", "vexpress-v2p-ca9.dtb")
+        self.emulator.boot(arch="armv7", kernel=kernel_file,
+                           kernel_cmdline=[
+                                        "console=ttyAMA0,115200"],
+                           options=["-initrd", cpio_file,
+                                        "-dtb", dtb_file,
+                                        "-M", "vexpress-a9"])
+        self.wait_boot()
+        self.setup_run_test_container()
diff --git a/support/testing/tests/package/test_lxc/kernel_config_frag b/support/testing/tests/package/test_lxc/kernel_config_frag
new file mode 100644
index 0000000000..32f8bdd65e
--- /dev/null
+++ b/support/testing/tests/package/test_lxc/kernel_config_frag
@@ -0,0 +1,20 @@ 
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_BLK_CGROUP=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_CGROUP_PIDS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_NETFILTER_XT_MATCH_CGROUP=y
+CONFIG_SOCK_CGROUP_DATA=y
+CONFIG_CGROUP_NET_PRIO=y
+CONFIG_CGROUP_NET_CLASSID=y
+CONFIG_NAMESPACES=y
+CONFIG_IPC_NS=y
+CONFIG_PID_NS=y
+CONFIG_UTS_NS=y
+CONFIG_USER_NS=y
+CONFIG_NET_NS=y
+CONFIG_BRIDGE=y
+CONFIG_VETH=y
diff --git a/support/testing/tests/package/test_lxc/test_lxc_rootfs_overlay/usr/bin/iperf3.sh b/support/testing/tests/package/test_lxc/test_lxc_rootfs_overlay/usr/bin/iperf3.sh
new file mode 100755
index 0000000000..7045ca4806
--- /dev/null
+++ b/support/testing/tests/package/test_lxc/test_lxc_rootfs_overlay/usr/bin/iperf3.sh
@@ -0,0 +1,2 @@ 
+#!/bin/sh
+iperf3 -s -1 > /tmp/iperf3.serv.log 2>&1
diff --git a/support/testing/tests/package/test_lxc/test_lxc_rootfs_overlay/usr/share/lxc/config/minimal-iperf3.conf b/support/testing/tests/package/test_lxc/test_lxc_rootfs_overlay/usr/share/lxc/config/minimal-iperf3.conf
new file mode 100644
index 0000000000..41cc5311d6
--- /dev/null
+++ b/support/testing/tests/package/test_lxc/test_lxc_rootfs_overlay/usr/share/lxc/config/minimal-iperf3.conf
@@ -0,0 +1,4 @@ 
+lxc.include = /usr/share/lxc/config/minimal.conf
+lxc.hook.version = 1
+lxc.hook.start-host = ip a add 192.168.1.1/24 dev lxc0
+lxc.init.cmd = tini -g iperf3.sh
diff --git a/support/testing/tests/package/test_lxc/test_lxc_rootfs_overlay/usr/share/lxc/config/minimal.conf b/support/testing/tests/package/test_lxc/test_lxc_rootfs_overlay/usr/share/lxc/config/minimal.conf
new file mode 100644
index 0000000000..7319821506
--- /dev/null
+++ b/support/testing/tests/package/test_lxc/test_lxc_rootfs_overlay/usr/share/lxc/config/minimal.conf
@@ -0,0 +1,6 @@ 
+lxc.autodev = 0
+lxc.net.0.type = veth
+lxc.net.0.veth.pair = lxc0
+lxc.net.0.name = eth0
+lxc.net.0.flags = up
+lxc.net.0.ipv4.address = 192.168.1.2/24