mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
test/case/infix_containers: new test, verify environment
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
Verifies Infix Docker container support:
|
||||
|
||||
- Basic web server container running in host network mode
|
||||
- Container enable/disable functionality via configuration
|
||||
- Container environment variable configuration and access
|
||||
- Common setup with a docker0 bridge, automatic VETH pairs to container(s)
|
||||
- Connecting a container with a VETH pair to a standard Linux bridge
|
||||
- Assigning a physical Ethernet interface to a container
|
||||
@@ -16,6 +18,8 @@ include::container_basic/Readme.adoc[]
|
||||
|
||||
include::container_enabled/Readme.adoc[]
|
||||
|
||||
include::container_environment/Readme.adoc[]
|
||||
|
||||
include::container_bridge/Readme.adoc[]
|
||||
|
||||
include::container_phys/Readme.adoc[]
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
container_environment.adoc
|
||||
@@ -0,0 +1,36 @@
|
||||
=== Container environment variables
|
||||
==== Description
|
||||
Verify that environment variables can be set in container configuration
|
||||
and are available inside the running container. Tests the 'env' list
|
||||
functionality by:
|
||||
|
||||
1. Creating a container with multiple environment variables
|
||||
2. Using a custom script to extract env vars and serve them via HTTP
|
||||
3. Fetching the served content to verify environment variables are set correctly
|
||||
|
||||
Uses the nftables container image with custom rc.local script.
|
||||
|
||||
==== Topology
|
||||
ifdef::topdoc[]
|
||||
image::{topdoc}../../test/case/infix_containers/container_environment/topology.svg[Container environment variables topology]
|
||||
endif::topdoc[]
|
||||
ifndef::topdoc[]
|
||||
ifdef::testgroup[]
|
||||
image::container_environment/topology.svg[Container environment variables topology]
|
||||
endif::testgroup[]
|
||||
ifndef::testgroup[]
|
||||
image::topology.svg[Container environment variables topology]
|
||||
endif::testgroup[]
|
||||
endif::topdoc[]
|
||||
==== Test sequence
|
||||
. Set up topology and attach to target DUT
|
||||
. Configure data interface with static IPv4
|
||||
. Create container with environment variables
|
||||
. Verify container has started
|
||||
. Verify environment variables are available via HTTP
|
||||
. Verify basic connectivity to data interface
|
||||
. Verify environment variables in HTTP response
|
||||
|
||||
|
||||
<<<
|
||||
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Container environment variables
|
||||
|
||||
Verify that environment variables can be set in container configuration
|
||||
and are available inside the running container. Tests the 'env' list
|
||||
functionality by:
|
||||
|
||||
1. Creating a container with multiple environment variables
|
||||
2. Using a custom script to extract env vars and serve them via HTTP
|
||||
3. Fetching the served content to verify environment variables are set correctly
|
||||
|
||||
Uses the nftables container image with custom rc.local script.
|
||||
"""
|
||||
import infamy
|
||||
from infamy.util import until, to_binary
|
||||
|
||||
|
||||
with infamy.Test() as test:
|
||||
NAME = "web-env"
|
||||
DUTIP = "10.0.0.2"
|
||||
OURIP = "10.0.0.1"
|
||||
|
||||
with test.step("Set up topology and attach to target DUT"):
|
||||
env = infamy.Env()
|
||||
target = env.attach("target", "mgmt")
|
||||
|
||||
if not target.has_model("infix-containers"):
|
||||
test.skip()
|
||||
|
||||
with test.step("Configure data interface with static IPv4"):
|
||||
_, ifname = env.ltop.xlate("target", "data")
|
||||
target.put_config_dict("ietf-interfaces", {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": f"{ifname}",
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": f"{DUTIP}",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
})
|
||||
|
||||
with test.step("Create container with environment variables"):
|
||||
script = to_binary("""#!/bin/sh
|
||||
# Create HTTP response with environment variables
|
||||
printf "HTTP/1.1 200 OK\\r\\n" > /var/www/response.txt
|
||||
printf "Content-Type: text/plain\\r\\n" >> /var/www/response.txt
|
||||
printf "Connection: close\\r\\n\\r\\n" >> /var/www/response.txt
|
||||
|
||||
# Add environment variables using printf to control encoding
|
||||
printf "TEST_VAR=\\"%s\\"\\n" "$TEST_VAR" >> /var/www/response.txt
|
||||
printf "APP_PORT=%s\\n" "$APP_PORT" >> /var/www/response.txt
|
||||
printf "DEBUG_MODE=\\"%s\\"\\n" "$DEBUG_MODE" >> /var/www/response.txt
|
||||
printf "PATH_WITH_SPACES=\\"%s\\"\\n" "$PATH_WITH_SPACES" >> /var/www/response.txt
|
||||
|
||||
while true; do
|
||||
nc -l -p 8080 < /var/www/response.txt 2>>/var/www/debug.log || sleep 1
|
||||
done
|
||||
""")
|
||||
|
||||
target.put_config_dict("infix-containers", {
|
||||
"containers": {
|
||||
"container": [
|
||||
{
|
||||
"name": f"{NAME}",
|
||||
"image": f"oci-archive:{infamy.Container.NFTABLES_IMAGE}",
|
||||
"env": [
|
||||
{"key": "TEST_VAR", "value": "hello-world"},
|
||||
{"key": "APP_PORT", "value": "8080"},
|
||||
{"key": "DEBUG_MODE", "value": "true"},
|
||||
{"key": "PATH_WITH_SPACES", "value": "/path with spaces/test"}
|
||||
],
|
||||
"network": {
|
||||
"host": True
|
||||
},
|
||||
"mount": [
|
||||
{
|
||||
"name": "rc.local",
|
||||
"content": script,
|
||||
"target": "/etc/rc.local",
|
||||
"mode": "0755"
|
||||
}
|
||||
],
|
||||
"volume": [{
|
||||
"name": "www",
|
||||
"target": "/var/www"
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
with test.step("Verify container has started"):
|
||||
c = infamy.Container(target)
|
||||
until(lambda: c.running(NAME), attempts=60)
|
||||
|
||||
with test.step("Verify environment variables are available via HTTP"):
|
||||
_, hport = env.ltop.xlate("host", "data")
|
||||
url = infamy.Furl(f"http://{DUTIP}:8080/env.html")
|
||||
|
||||
with infamy.IsolatedMacVlan(hport) as ns:
|
||||
ns.addip(OURIP)
|
||||
|
||||
with test.step("Verify basic connectivity to data interface"):
|
||||
ns.must_reach(DUTIP)
|
||||
|
||||
with test.step("Verify environment variables in HTTP response"):
|
||||
until(lambda: url.nscheck(ns, "TEST_VAR=\"hello-world\""), attempts=10)
|
||||
until(lambda: url.nscheck(ns, "APP_PORT=8080"), attempts=10)
|
||||
until(lambda: url.nscheck(ns, "DEBUG_MODE=\"true\""), attempts=10)
|
||||
until(lambda: url.nscheck(ns, "PATH_WITH_SPACES=\"/path with spaces/test\""), attempts=10)
|
||||
|
||||
test.succeed()
|
||||
@@ -0,0 +1,24 @@
|
||||
graph "1x2" {
|
||||
layout="neato";
|
||||
overlap="false";
|
||||
esep="+80";
|
||||
|
||||
node [shape=record, fontname="DejaVu Sans Mono, Book"];
|
||||
edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"];
|
||||
|
||||
host [
|
||||
label="host | { <mgmt> mgmt | <data> data }",
|
||||
pos="0,12!",
|
||||
requires="controller",
|
||||
];
|
||||
|
||||
target [
|
||||
label="{ <mgmt> mgmt | <data> data } | target",
|
||||
pos="10,12!",
|
||||
|
||||
requires="infix",
|
||||
];
|
||||
|
||||
host:mgmt -- target:mgmt [requires="mgmt", color=lightgrey]
|
||||
host:data -- target:data [color=black]
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
|
||||
<!-- 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,-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="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,-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>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -6,6 +6,10 @@
|
||||
- name: container_enabled
|
||||
case: container_enabled/test.py
|
||||
|
||||
# Disabled for v25.08, new/unstable
|
||||
# - name: container_environment
|
||||
# case: container_environment/test.py
|
||||
|
||||
- name: container_bridge
|
||||
case: container_bridge/test.py
|
||||
|
||||
|
||||
Reference in New Issue
Block a user