summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2023-03-02 19:35:38 +0100
committerLubomir Rintel <lkundrak@v3.sk>2023-03-21 23:35:42 +0100
commitd89d42bf23170b4923f71bc415fe071f7c03978a (patch)
tree4c56af7e6736d71e28bc30c0114af7737ccfe16b
parentad6878d50a10c0a6d0c36c3487d41ebce5f2ee74 (diff)
downloadNetworkManager-d89d42bf23170b4923f71bc415fe071f7c03978a.tar.gz
tests/client: test nm-cloud-setup
Some fairly rudimentary testing of nm-cloud-setup.
-rw-r--r--Makefile.am7
-rw-r--r--src/tests/client/meson.build17
-rwxr-xr-xsrc/tests/client/test-client.py161
-rwxr-xr-xsrc/tests/client/test-client.sh5
4 files changed, 188 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am
index 0f827c6763..cd30c7201e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5472,6 +5472,13 @@ check-local-tests-client: src/nmcli/nmcli src/tests/client/test-client.py
check_local += check-local-tests-client
+check-local-tests-cloud-setup: src/nm-cloud-setup/nm-cloud-setup src/tests/client/test-client.py
+ LIBTOOL="$(LIBTOOL)" "$(srcdir)/src/tests/client/test-client.sh" "$(builddir)" "$(srcdir)" "$(PYTHON)" -- TestNmCloudSetup
+
+if BUILD_NM_CLOUD_SETUP
+check_local += check-local-tests-cloud-setup
+endif
+
CLEANFILES += src/tests/client/test-client.log
EXTRA_DIST += \
diff --git a/src/tests/client/meson.build b/src/tests/client/meson.build
index 6a6891354d..1c349cc1ee 100644
--- a/src/tests/client/meson.build
+++ b/src/tests/client/meson.build
@@ -15,3 +15,20 @@ test(
],
timeout: 120,
)
+
+if enable_nm_cloud_setup
+ test(
+ 'check-local-tests-cloud-setup',
+ find_program(join_paths(source_root, 'src/tests/client/test-client.sh')),
+ args: [
+ build_root,
+ source_root,
+ python.path(),
+ '--',
+ 'TestNmCloudSetup',
+ ],
+ env: [
+ 'LIBTOOL=',
+ ],
+ )
+endif
diff --git a/src/tests/client/test-client.py b/src/tests/client/test-client.py
index 859a5280be..e603203e3e 100755
--- a/src/tests/client/test-client.py
+++ b/src/tests/client/test-client.py
@@ -68,6 +68,10 @@ ENV_NM_TEST_CLIENT_BUILDDIR = "NM_TEST_CLIENT_BUILDDIR"
# In particular, you can test also a nmcli binary installed somewhere else.
ENV_NM_TEST_CLIENT_NMCLI_PATH = "NM_TEST_CLIENT_NMCLI_PATH"
+# (optional) Path to nm-cloud-setup. By default, it looks for nm-cloud-setup
+# in build dir.
+ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH = "NM_TEST_CLIENT_CLOUD_SETUP_PATH"
+
# (optional) The test also compares tranlsated output (l10n). This requires,
# that you first install the translation in the right place. So, by default,
# if a test for a translation fails, it will mark the test as skipped, and not
@@ -140,6 +144,12 @@ try:
except ImportError:
pexpect = None
+try:
+ from http.server import HTTPServer
+ from http.server import BaseHTTPRequestHandler
+except ImportError:
+ HTTPServer = None
+
###############################################################################
@@ -165,6 +175,14 @@ class PathConfiguration:
return v
@staticmethod
+ def test_cloud_meta_mock_path():
+ v = os.path.abspath(
+ PathConfiguration.top_srcdir() + "/tools/test-cloud-meta-mock.py"
+ )
+ assert os.path.exists(v), 'Cannot find cloud metadata mock server at "%s"' % (v)
+ return v
+
+ @staticmethod
def canonical_script_filename():
p = "src/tests/client/test-client.py"
assert (PathConfiguration.top_srcdir() + "/" + p) == os.path.abspath(__file__)
@@ -551,6 +569,20 @@ class Configuration:
pass
if not os.path.exists(v):
raise Exception("Missing nmcli binary. Set NM_TEST_CLIENT_NMCLI_PATH?")
+ elif name == ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH:
+ v = os.environ.get(ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, None)
+ if v is None:
+ try:
+ v = os.path.abspath(
+ self.get(ENV_NM_TEST_CLIENT_BUILDDIR)
+ + "/src/nm-cloud-setup/nm-cloud-setup"
+ )
+ except:
+ pass
+ if not os.path.exists(v):
+ raise Exception(
+ "Missing nm-cloud-setup binary. Set NM_TEST_CLIENT_CLOUD_SETUP_PATH?"
+ )
elif name == ENV_NM_TEST_CLIENT_CHECK_L10N:
# if we test locales other than 'C', the output of nmcli depends on whether
# nmcli can load the translations. Unfortunately, I cannot find a way to
@@ -751,6 +783,16 @@ class NMStubServer:
iface_name = ""
self.op_SetProperties([(path, [(iface_name, [(propname, value)])])])
+ def addAndActivateConnection(
+ self, connection, device, specific_object="", delay=None
+ ):
+ if delay is not None:
+ self.op_SetActiveConnectionStateChangedDelay(device, delay)
+ nm_iface = self._conn_get_main_object(self._conn)
+ self.op_AddAndActivateConnection(
+ connection, device, specific_object, dbus_iface=nm_iface
+ )
+
###############################################################################
@@ -2094,6 +2136,125 @@ class TestNmcli(TestNmClient):
###############################################################################
+class TestNmCloudSetup(TestNmClient):
+ def cloud_setup_test(func):
+ """
+ Runs the mock NetworkManager along with a mock cloud metadata service.
+ """
+
+ def f(self):
+ if pexpect is None:
+ raise unittest.SkipTest("pexpect not available")
+
+ s = socket.socket()
+ s.set_inheritable(True)
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
+ s.bind(("localhost", 0))
+
+ # The same value as Python's TCPServer uses.
+ # Chosen by summoning the sprit of TCP under influence of
+ # hallucinogenic substances.
+ s.listen(5)
+
+ def pass_socket():
+ os.dup2(s.fileno(), 3, inheritable=True)
+
+ service_path = PathConfiguration.test_cloud_meta_mock_path()
+ env = os.environ.copy()
+ env["LISTEN_FDS"] = "1"
+ p = subprocess.Popen(
+ [sys.executable, service_path],
+ stdin=subprocess.PIPE,
+ env=env,
+ pass_fds=(s.fileno(),),
+ preexec_fn=pass_socket,
+ )
+
+ self.md_url = "http://%s:%d" % s.getsockname()
+ s.close()
+
+ self.srv_start()
+ func(self)
+ self._nm_test_post()
+
+ p.terminate()
+ p.wait()
+
+ return f
+
+ @cloud_setup_test
+ def test_ec2(self):
+
+ # Add a device with an active connection that has IPv4 configured
+ self.srv.op_AddObj("WiredDevice", iface="eth0")
+ self.srv.addAndActivateConnection(
+ {
+ "connection": {"type": "802-3-ethernet", "id": "con-eth0"},
+ "ipv4": {"method": "auto"},
+ },
+ "/org/freedesktop/NetworkManager/Devices/1",
+ delay=0,
+ )
+
+ # The second connection has no IPv4
+ self.srv.op_AddObj("WiredDevice", iface="eth1")
+ self.srv.addAndActivateConnection(
+ {"connection": {"type": "802-3-ethernet", "id": "con-eth1"}},
+ "/org/freedesktop/NetworkManager/Devices/2",
+ "",
+ delay=0,
+ )
+
+ # Run nm-cloud-setup for the first time
+ nmc = self.call_pexpect(
+ ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH,
+ [],
+ {
+ "NM_CLOUD_SETUP_EC2_HOST": self.md_url,
+ "NM_CLOUD_SETUP_LOG": "trace",
+ "NM_CLOUD_SETUP_EC2": "yes",
+ },
+ )
+
+ nmc.pexp.expect("provider ec2 detected")
+ nmc.pexp.expect("found interfaces: 9E:C0:3E:92:24:2D, 53:E9:7E:52:8D:A8")
+ nmc.pexp.expect("get-config: starting")
+ nmc.pexp.expect("get-config: success")
+ nmc.pexp.expect("meta data received")
+ # One of the devices has no IPv4 configuration to be modified
+ nmc.pexp.expect("device has no suitable applied connection. Skip")
+ # The other one was lacking an address set it up.
+ nmc.pexp.expect("some changes were applied for provider ec2")
+ nmc.pexp.expect(pexpect.EOF)
+
+ # Run nm-cloud-setup for the second time
+ nmc = self.call_pexpect(
+ ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH,
+ [],
+ {
+ "NM_CLOUD_SETUP_EC2_HOST": self.md_url,
+ "NM_CLOUD_SETUP_LOG": "trace",
+ "NM_CLOUD_SETUP_EC2": "yes",
+ },
+ )
+
+ nmc.pexp.expect("provider ec2 detected")
+ nmc.pexp.expect("found interfaces: 9E:C0:3E:92:24:2D, 53:E9:7E:52:8D:A8")
+ nmc.pexp.expect("get-config: starting")
+ nmc.pexp.expect("get-config: success")
+ nmc.pexp.expect("meta data received")
+ # No changes this time
+ nmc.pexp.expect('device needs no update to applied connection "con-eth0"')
+ nmc.pexp.expect("no changes were applied for provider ec2")
+ nmc.pexp.expect(pexpect.EOF)
+
+ Util.valgrind_check_log(nmc.valgrind_log, "test_ec2")
+
+
+###############################################################################
+
+
def main():
global dbus_session_inited
diff --git a/src/tests/client/test-client.sh b/src/tests/client/test-client.sh
index a636f5fb93..dd08e4d889 100755
--- a/src/tests/client/test-client.sh
+++ b/src/tests/client/test-client.sh
@@ -71,7 +71,6 @@ fi
test -d "$BUILDDIR" || die "BUILDDIR \"$BUILDDIR\" does not exist?"
test -d "$SRCDIR" || die "SRCDIR \"$SRCDIR\" does not exist?"
-test -f "$BUILDDIR/src/nmcli/nmcli" || die "\"$BUILDDIR/src/nmcli/nmcli\" does not exist?"
if test -f "$BUILDDIR/src/libnm-client-impl/.libs/libnm.so" ; then
LIBDIR="$BUILDDIR/src/libnm-client-impl/.libs"
@@ -84,6 +83,7 @@ fi
mkdir -p "$BUILDDIR/src/tests/client/" || die "failure to create build output directory \"$BUILDDIR/src/tests/client/\""
export NM_TEST_CLIENT_NMCLI_PATH="$BUILDDIR/src/nmcli/nmcli"
+export NM_TEST_CLIENT_CLOUD_SETUP_PATH="$BUILDDIR/src/nm-cloud-setup/nm-cloud-setup"
export GI_TYPELIB_PATH="$BUILDDIR/src/libnm-client-impl${GI_TYPELIB_PATH:+:$GI_TYPELIB_PATH}"
export LD_LIBRARY_PATH="$LIBDIR${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
export NM_TEST_CLIENT_BUILDDIR="$BUILDDIR"
@@ -91,7 +91,8 @@ export NM_TEST_CLIENT_BUILDDIR="$BUILDDIR"
# Run nmcli at least once. With libtool, nmcli is a shell script and with LTO
# this seems to perform some slow setup during the first run. If we do that
# during the test, it will timeout and fail.
-"$NM_TEST_CLIENT_NMCLI_PATH" --version &>/dev/null
+"$NM_TEST_CLIENT_NMCLI_PATH" --version &>/dev/null || :
+"$NM_TEST_CLIENT_CLOUD_SETUP_PATH" --invalid &>/dev/null || :
# we first collect all the output in "test-client.log" and print it at once
# afterwards. The only reason is that when you run with `make -j` that the