mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-01 13:55:36 +00:00
tests/client: test nm-cloud-setup
Some fairly rudimentary testing of nm-cloud-setup.
This commit is contained in:
parent
ad6878d50a
commit
d89d42bf23
|
@ -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 += \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
@ -164,6 +174,14 @@ class PathConfiguration:
|
|||
assert os.path.exists(v), 'Cannot find test server at "%s"' % (v)
|
||||
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"
|
||||
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue