diff options
| author | Michael Biebl <biebl@debian.org> | 2025-02-12 13:46:50 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2025-02-12 13:46:50 +0100 |
| commit | 8bdf070ff046f482f6eb5e2b15ebc216f5d1e3da (patch) | |
| tree | f706478d189d54c6532e8863d4b0d5ff5575af60 /src/tests/client/test-client.py | |
| parent | 818258cf34b83fbc754633295e1052d4752d7b15 (diff) | |
New upstream version 1.51.90 upstream/1.51.90
Diffstat (limited to 'src/tests/client/test-client.py')
| -rwxr-xr-x | src/tests/client/test-client.py | 727 |
1 files changed, 459 insertions, 268 deletions
diff --git a/src/tests/client/test-client.py b/src/tests/client/test-client.py index 60853e6d..d01b3bce 100755 --- a/src/tests/client/test-client.py +++ b/src/tests/client/test-client.py @@ -19,18 +19,14 @@ from __future__ import print_function # # For that, you'd setup your system correctly (see SETUP below) and then simply: # -# $ NM_TEST_REGENERATE=1 make check-local-tests-client -# # Or `NM_TEST_REGENERATE=1 make check -j 10` +# $ meson -Ddocs=true --prefix=/tmp/nm1 build +# $ ninja -C build +# $ ninja -C build install +# $ NM_TEST_REGENERATE=1 ninja -C build test # $ git diff ... ; git add ... # # The previous step regenerated the expected output. Review the changes # # and consider whether they are correct. Then commit the changes to git. # -# With meson, you can do -# $ meson -Ddocs=true --prefix=/tmp/nm1 build -# $ ninja -C build -# $ ninja -C build install -# $ NM_TEST_REGENERATE=1 ninja -C build test -# # Beware that you need to install the sources, and beware to choose a prefix that doesn't # mess up your system (see SETUP below). # @@ -52,7 +48,7 @@ from __future__ import print_function # # Ensure that the built nmcli has Polish locale working. If not, # # you probably need to first `make install` the application at the # # correct prefix. Take care to configure the build with the desired -# # prefix, like `./configure --prefix=/opt/tmp`. Usually, you want to avoid +# # prefix, like `meson setup build --prefix=/opt/tmp`. Usually, you want to avoid # # using /usr as prefix, because that might overwrite files from your # # package management system. # @@ -90,6 +86,9 @@ ENV_NM_TEST_REGENERATE = "NM_TEST_REGENERATE" # numbers enabled. ENV_NM_TEST_WITH_LINENO = "NM_TEST_WITH_LINENO" +# Log pexpect output to stderr, for debuging +ENV_NM_TEST_LOG_PEXPECT = "NM_TEST_LOG_PEXPECT" + ENV_NM_TEST_ASAN_OPTIONS = "NM_TEST_ASAN_OPTIONS" ENV_NM_TEST_LSAN_OPTIONS = "NM_TEST_LSAN_OPTIONS" ENV_NM_TEST_UBSAN_OPTIONS = "NM_TEST_UBSAN_OPTIONS" @@ -689,29 +688,6 @@ class Util: return argv, valgrind_log @staticmethod - def cmd_call_pexpect(cmd_path, args, extra_env): - argv, valgrind_log = Util.cmd_create_argv(cmd_path, args) - env = Util.cmd_create_env(extra_env=extra_env) - - pexp = pexpect.spawn(argv[0], argv[1:], timeout=10, env=env) - - pexp.str_last_chars = 100000 - - typ = collections.namedtuple("CallPexpect", ["pexp", "valgrind_log"]) - return typ(pexp, valgrind_log) - - @staticmethod - def cmd_call_pexpect_nmcli(args, extra_env={}): - extra_env = extra_env.copy() - extra_env.update({"NO_COLOR": "1"}) - - return Util.cmd_call_pexpect( - ENV_NM_TEST_CLIENT_NMCLI_PATH, - args, - extra_env, - ) - - @staticmethod def get_nmcli_version(): ver = NM.utils_version() micro = ver & 0xFF @@ -737,7 +713,7 @@ class Configuration: ) if not os.path.isdir(v): raise Exception("Missing builddir. Set NM_TEST_CLIENT_BUILDDIR?") - elif name == ENV_NM_TEST_CLIENT_NMCLI_PATH: + elif name == "ENV_NM_TEST_CLIENT_NMCLI_UNCHECKED_PATH": v = os.environ.get(ENV_NM_TEST_CLIENT_NMCLI_PATH, None) if v is None: try: @@ -746,6 +722,8 @@ class Configuration: ) except: pass + elif name == ENV_NM_TEST_CLIENT_NMCLI_PATH: + v = self.get("ENV_NM_TEST_CLIENT_NMCLI_UNCHECKED_PATH") 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: @@ -779,6 +757,8 @@ class Configuration: v = Util.is_bool(os.environ.get(ENV_NM_TEST_REGENERATE, None)) elif name == ENV_NM_TEST_WITH_LINENO: v = Util.is_bool(os.environ.get(ENV_NM_TEST_WITH_LINENO, None)) + elif name == ENV_NM_TEST_LOG_PEXPECT: + v = Util.is_bool(os.environ.get(ENV_NM_TEST_LOG_PEXPECT, None)) elif name == ENV_NM_TEST_VALGRIND: if self.get(ENV_NM_TEST_REGENERATE): v = False @@ -808,7 +788,7 @@ class Configuration: v = os.environ.get(name, None) if v is None: v = os.path.abspath( - os.path.dirname(self.get(ENV_NM_TEST_CLIENT_NMCLI_PATH)) + os.path.dirname(self.get("ENV_NM_TEST_CLIENT_NMCLI_UNCHECKED_PATH")) + "/../../libtool" ) if not os.path.isfile(v): @@ -1071,6 +1051,7 @@ class NMTestContext: self._calling_num = {} self._skip_test_for_l10n_diff = [] self._async_jobs = [] + self._nmc = None self.ctx_results = [] self.srv = None @@ -1129,112 +1110,60 @@ class NMTestContext: def async_append_job(self, async_job): self._async_jobs.append(async_job) - def run_post(self): - self.async_wait() + def cmd_call_pexpect(self, cmd_path, args, extra_env): + if self._nmc is not None: + raise Exception("Unfinished pexpect run exists") - self.srv_shutdown() + argv, valgrind_log = Util.cmd_create_argv(cmd_path, args) + env = Util.cmd_create_env(extra_env=extra_env) - self._calling_num = None + pexp = pexpect.spawn(argv[0], argv[1:], timeout=10, env=env, encoding="utf-8") + if conf.get(ENV_NM_TEST_LOG_PEXPECT): + pexp.logfile = sys.stderr - results = self.ctx_results - self.ctx_results = None + pexp.str_last_chars = 100000 - if len(results) == 0: - return + typ = collections.namedtuple("CallPexpect", ["pexp", "valgrind_log"]) + self._nmc = typ(pexp, valgrind_log) + return pexp - skip_test_for_l10n_diff = self._skip_test_for_l10n_diff - self._skip_test_for_l10n_diff = None + def cmd_call_pexpect_nmcli(self, args, extra_env={}): + extra_env = extra_env.copy() + extra_env.update({"NO_COLOR": "1"}) - filename = os.path.abspath( - PathConfiguration.srcdir() - + "/test-client.check-on-disk/" - + self.testMethodName - + ".expected" + return self.cmd_call_pexpect( + ENV_NM_TEST_CLIENT_NMCLI_PATH, + args, + extra_env, ) - regenerate = conf.get(ENV_NM_TEST_REGENERATE) + def cmd_close_pexpect(self, pexp=None, signal=None): + if self._nmc is None: + raise Exception("No pexpect run exists") - content_expect, results_expect = Util.file_read_expected(filename) + if signal is not None: + pexp.kill(signal) + pexp.expect(pexpect.EOF) + pexp.close() - if results_expect is None: - if not regenerate: - self.fail( - "Failed to parse expected file '%s'. Let the test write the file by rerunning with NM_TEST_REGENERATE=1" - % (filename) - ) - else: - for i in range(0, min(len(results_expect), len(results))): - n = results[i] - if results_expect[i] == n["content"]: - continue - if regenerate: - continue - if n["ignore_l10n_diff"]: - skip_test_for_l10n_diff.append(n["test_name"]) - continue - print( - "\n\n\nThe file '%s' does not have the expected content:" - % (filename) - ) - print("ACTUAL OUTPUT:\n[[%s]]\n" % (n["content"])) - print("EXPECT OUTPUT:\n[[%s]]\n" % (results_expect[i])) - print( - "Let the test write the file by rerunning with NM_TEST_REGENERATE=1" - ) - print( - "See howto in %s for details.\n" - % (PathConfiguration.canonical_script_filename()) - ) - sys.stdout.flush() - self.fail( - "Unexpected output of command, expected %s. Rerun test with NM_TEST_REGENERATE=1 to regenerate files" - % (filename) - ) - if len(results_expect) != len(results): - if not regenerate: - print( - "\n\n\nThe number of tests in %s does not match the expected content (%s vs %s):" - % (filename, len(results_expect), len(results)) - ) - if len(results_expect) < len(results): - print( - "ACTUAL OUTPUT:\n[[%s]]\n" - % (results[len(results_expect)]["content"]) - ) - else: - print( - "EXPECT OUTPUT:\n[[%s]]\n" % (results_expect[len(results)]) - ) - print( - "Let the test write the file by rerunning with NM_TEST_REGENERATE=1" - ) - print( - "See howto in %s for details.\n" - % (PathConfiguration.canonical_script_filename()) - ) - sys.stdout.flush() - self.fail( - "Unexpected output of command, expected %s. Rerun test with NM_TEST_REGENERATE=1 to regenerate files" - % (filename) - ) + valgrind_log = self._nmc.valgrind_log + self._nmc = None + return (pexp.exitstatus, pexp.signalstatus, valgrind_log) - if regenerate: - content_new = b"".join([r["content"] for r in results]) - if content_new != content_expect: - try: - with open(filename, "wb") as content_file: - content_file.write(content_new) - except Exception as e: - self.fail("Failure to write '%s': %s" % (filename, e)) + def pexpect_cleanup(self): + if self._nmc is None: + return - if skip_test_for_l10n_diff: - # nmcli loads translations from the installation path. This failure commonly - # happens because you did not install the binary in the --prefix, before - # running the test. Hence, translations are not available or differ. - raise unittest.SkipTest( - "Skipped asserting for localized tests %s. Set NM_TEST_CLIENT_CHECK_L10N=1 to force fail." - % (",".join(skip_test_for_l10n_diff)) + (exitstatus, signalstatus, _valgrind_log) = self.cmd_close_pexpect( + self._nmc.pexp + ) + if signalstatus is not None: + print( + "*** pexpect'd process killed by %s ***" + % Util.signal_no_to_str(signalstatus) ) + if exitstatus is not None: + print("*** pexpect'd process exited with status = %d ***" % exitstatus) ############################################################################### @@ -1245,6 +1174,7 @@ class TestNmcli(unittest.TestCase): Util.skip_without_dbus_session() Util.skip_without_NM() self.ctx = NMTestContext(self._testMethodName) + self._skip_test_for_l10n_diff = [] def call_nmcli_l( self, @@ -1505,18 +1435,125 @@ class TestNmcli(unittest.TestCase): self.ctx.async_start(wait_all=sync_barrier) + def run_post(self): + self.ctx.async_wait() + self.ctx.srv_shutdown() + self.ctx.pexpect_cleanup() + + self.ctx._calling_num = None + + results = self.ctx.ctx_results + self.ctx.ctx_results = None + + if len(results) == 0: + return + + skip_test_for_l10n_diff = self._skip_test_for_l10n_diff + self._skip_test_for_l10n_diff = None + + filename = os.path.abspath( + PathConfiguration.srcdir() + + "/test-client.check-on-disk/" + + self._testMethodName + + ".expected" + ) + + regenerate = conf.get(ENV_NM_TEST_REGENERATE) + + content_expect, results_expect = Util.file_read_expected(filename) + + if results_expect is None: + if not regenerate: + self.fail( + "Failed to parse expected file '%s'. Let the test write the file by rerunning with NM_TEST_REGENERATE=1" + % (filename) + ) + else: + for i in range(0, min(len(results_expect), len(results))): + n = results[i] + if results_expect[i] == n["content"]: + continue + if regenerate: + continue + if n["ignore_l10n_diff"]: + skip_test_for_l10n_diff.append(n["test_name"]) + continue + print( + "\n\n\nThe file '%s' does not have the expected content:" + % (filename) + ) + print("ACTUAL OUTPUT:\n[[%s]]\n" % (n["content"])) + print("EXPECT OUTPUT:\n[[%s]]\n" % (results_expect[i])) + print( + "Let the test write the file by rerunning with NM_TEST_REGENERATE=1" + ) + print( + "See howto in %s for details.\n" + % (PathConfiguration.canonical_script_filename()) + ) + sys.stdout.flush() + self.fail( + "Unexpected output of command, expected %s. Rerun test with NM_TEST_REGENERATE=1 to regenerate files" + % (filename) + ) + if len(results_expect) != len(results): + if not regenerate: + print( + "\n\n\nThe number of tests in %s does not match the expected content (%s vs %s):" + % (filename, len(results_expect), len(results)) + ) + if len(results_expect) < len(results): + print( + "ACTUAL OUTPUT:\n[[%s]]\n" + % (results[len(results_expect)]["content"]) + ) + else: + print( + "EXPECT OUTPUT:\n[[%s]]\n" % (results_expect[len(results)]) + ) + print( + "Let the test write the file by rerunning with NM_TEST_REGENERATE=1" + ) + print( + "See howto in %s for details.\n" + % (PathConfiguration.canonical_script_filename()) + ) + sys.stdout.flush() + self.fail( + "Unexpected output of command, expected %s. Rerun test with NM_TEST_REGENERATE=1 to regenerate files" + % (filename) + ) + + if regenerate: + content_new = b"".join([r["content"] for r in results]) + if content_new != content_expect: + try: + with open(filename, "wb") as content_file: + content_file.write(content_new) + except Exception as e: + self.fail("Failure to write '%s': %s" % (filename, e)) + + if skip_test_for_l10n_diff: + # nmcli loads translations from the installation path. This failure commonly + # happens because you did not install the binary in the --prefix, before + # running the test. Hence, translations are not available or differ. + raise unittest.SkipTest( + "Skipped asserting for localized tests %s. Set NM_TEST_CLIENT_CHECK_L10N=1 to force fail." + % (",".join(skip_test_for_l10n_diff)) + ) + def nm_test(func): def f(self): self.ctx.srv_start() func(self) - self.ctx.run_post() + self.run_post() return f def nm_test_no_dbus(func): def f(self): func(self) - self.ctx.run_post() + self.run_post() return f @@ -2188,26 +2225,31 @@ class TestNmcli(unittest.TestCase): @Util.skip_without_pexpect @nm_test def test_ask_mode(self): - nmc = Util.cmd_call_pexpect_nmcli(["--ask", "c", "add"]) - nmc.pexp.expect("Connection type:") - nmc.pexp.sendline("ethernet") - nmc.pexp.expect("Interface name:") - nmc.pexp.sendline("eth0") - nmc.pexp.expect("There are 3 optional settings for Wired Ethernet.") - nmc.pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") - nmc.pexp.sendline("no") - nmc.pexp.expect("There are 2 optional settings for IPv4 protocol.") - nmc.pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") - nmc.pexp.sendline("no") - nmc.pexp.expect("There are 2 optional settings for IPv6 protocol.") - nmc.pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") - nmc.pexp.sendline("no") - nmc.pexp.expect("There are 4 optional settings for Proxy.") - nmc.pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") - nmc.pexp.sendline("no") - nmc.pexp.expect(r"Connection 'ethernet' \(.*\) successfully added.") - nmc.pexp.expect(pexpect.EOF) - Util.valgrind_check_log(nmc.valgrind_log, "test_ask_mode") + pexp = self.ctx.cmd_call_pexpect_nmcli(["--ask", "c", "add"]) + pexp.expect("Connection type:") + pexp.sendline("ethernet") + pexp.expect("Interface name:") + pexp.sendline("eth0") + pexp.expect("There are 3 optional settings for Wired Ethernet.") + pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") + pexp.sendline("no") + pexp.expect("There are 2 optional settings for IPv4 protocol.") + pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") + pexp.sendline("no") + pexp.expect("There are 2 optional settings for IPv6 protocol.") + pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") + pexp.sendline("no") + pexp.expect("There are 4 optional settings for Proxy.") + pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") + pexp.sendline("no") + pexp.expect(r"Connection 'ethernet' \(.*\) successfully added.") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_ask_mode") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") @Util.skip_without_pexpect @nm_test @@ -2218,26 +2260,26 @@ class TestNmcli(unittest.TestCase): "DBUS_SESSION_BUS_ADDRESS": "very:invalid", } - nmc = Util.cmd_call_pexpect_nmcli( + pexp = self.ctx.cmd_call_pexpect_nmcli( ["--offline", "--ask", "c", "add"], extra_env=no_dbus_env ) - nmc.pexp.expect("Connection type:") - nmc.pexp.sendline("ethernet") - nmc.pexp.expect("Interface name:") - nmc.pexp.sendline("eth0") - nmc.pexp.expect("There are 3 optional settings for Wired Ethernet.") - nmc.pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") - nmc.pexp.sendline("no") - nmc.pexp.expect("There are 2 optional settings for IPv4 protocol.") - nmc.pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") - nmc.pexp.sendline("no") - nmc.pexp.expect("There are 2 optional settings for IPv6 protocol.") - nmc.pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") - nmc.pexp.sendline("no") - nmc.pexp.expect("There are 4 optional settings for Proxy.") - nmc.pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") - nmc.pexp.sendline("no") - nmc.pexp.expect( + pexp.expect("Connection type:") + pexp.sendline("ethernet") + pexp.expect("Interface name:") + pexp.sendline("eth0") + pexp.expect("There are 3 optional settings for Wired Ethernet.") + pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") + pexp.sendline("no") + pexp.expect("There are 2 optional settings for IPv4 protocol.") + pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") + pexp.sendline("no") + pexp.expect("There are 2 optional settings for IPv6 protocol.") + pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") + pexp.sendline("no") + pexp.expect("There are 4 optional settings for Proxy.") + pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") + pexp.sendline("no") + pexp.expect( r"\[connection\]\r\n" r"id=ethernet\r\n" r"uuid=.*\r\n" @@ -2255,43 +2297,58 @@ class TestNmcli(unittest.TestCase): r"\r\n" r"\[proxy\]\r\n" ) - nmc.pexp.expect(pexpect.EOF) - Util.valgrind_check_log(nmc.valgrind_log, "test_ask_offline") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_ask_offline") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") @Util.skip_without_pexpect @nm_test def test_monitor(self): def start_mon(self): - nmc = Util.cmd_call_pexpect_nmcli(["monitor"]) - nmc.pexp.expect("NetworkManager is running") - return nmc + pexp = self.ctx.cmd_call_pexpect_nmcli(["monitor"]) + pexp.expect("NetworkManager is running") + return pexp - def end_mon(self, nmc): - nmc.pexp.kill(signal.SIGINT) - nmc.pexp.expect(pexpect.EOF) - Util.valgrind_check_log(nmc.valgrind_log, "test_monitor") + def end_mon(self, pexp): + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect( + pexp, signal=signal.SIGINT + ) + Util.valgrind_check_log(valgrind_log, "test_monitor") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual( + exitstatus, + 128 + signal.SIGINT, + "Unexpectedly returned a non-zero status", + ) - nmc = start_mon(self) + pexp = start_mon(self) self.ctx.srv.op_AddObj("WiredDevice", iface="eth0") - nmc.pexp.expect("eth0: device created\r\n") + pexp.expect("eth0: device created\r\n") self.ctx.srv.addConnection( {"connection": {"type": "802-3-ethernet", "id": "con-1"}} ) - nmc.pexp.expect("con-1: connection profile created\r\n") + pexp.expect("con-1: connection profile created\r\n") - end_mon(self, nmc) + end_mon(self, pexp) - nmc = start_mon(self) + pexp = start_mon(self) self.ctx.srv_shutdown() Util.pexpect_expect_all( - nmc.pexp, + pexp, "con-1: connection profile removed", "eth0: device removed", ) - nmc.pexp.expect("NetworkManager is stopped") - end_mon(self, nmc) + pexp.expect("NetworkManager is stopped") + end_mon(self, pexp) @nm_test_no_dbus # we need dbus, but we need to pass arguments to srv_start def test_version_warn(self): @@ -2373,7 +2430,9 @@ class TestNmCloudSetup(unittest.TestCase): func(self) except Exception as e: error = e - self.ctx.run_post() + self.ctx.async_wait() + self.ctx.srv_shutdown() + self.ctx.pexpect_cleanup() self.md_conn.close() p.stdin.close() @@ -2456,7 +2515,8 @@ class TestNmCloudSetup(unittest.TestCase): ) # Run nm-cloud-setup for the first time - nmc = Util.cmd_call_pexpect( + + pexp = self.ctx.cmd_call_pexpect( ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, [], { @@ -2466,19 +2526,25 @@ class TestNmCloudSetup(unittest.TestCase): }, ) - nmc.pexp.expect("provider aliyun detected") - nmc.pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") - nmc.pexp.expect("get-config: start fetching meta data") - nmc.pexp.expect("get-config: success") - nmc.pexp.expect("meta data received") + pexp.expect("provider aliyun detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("get-config: start fetching meta data") + pexp.expect("get-config: success") + 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") + 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 aliyun") - nmc.pexp.expect(pexpect.EOF) + pexp.expect("some changes were applied for provider aliyun") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_aliyun") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") # Run nm-cloud-setup for the second time - nmc = Util.cmd_call_pexpect( + pexp = self.ctx.cmd_call_pexpect( ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, [], { @@ -2488,17 +2554,21 @@ class TestNmCloudSetup(unittest.TestCase): }, ) - nmc.pexp.expect("provider aliyun detected") - nmc.pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") - nmc.pexp.expect("get-config: starting") - nmc.pexp.expect("get-config: success") - nmc.pexp.expect("meta data received") + pexp.expect("provider aliyun detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("get-config: starting") + pexp.expect("get-config: success") + 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 aliyun") - nmc.pexp.expect(pexpect.EOF) - - Util.valgrind_check_log(nmc.valgrind_log, "test_aliyun") + pexp.expect('device needs no update to applied connection "con-eth0"') + pexp.expect("no changes were applied for provider aliyun") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_aliyun") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") @cloud_setup_test def test_azure(self): @@ -2535,7 +2605,7 @@ class TestNmCloudSetup(unittest.TestCase): self._mock_path(_azure_iface + "1/ipv4/subnet/0/prefix/" + _azure_query, "20") # Run nm-cloud-setup for the first time - nmc = Util.cmd_call_pexpect( + pexp = self.ctx.cmd_call_pexpect( ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, [], { @@ -2545,26 +2615,32 @@ class TestNmCloudSetup(unittest.TestCase): }, ) - nmc.pexp.expect("provider azure detected") - nmc.pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") - nmc.pexp.expect("found azure interfaces: 2") - nmc.pexp.expect(r"interface\[0]: found a matching device with hwaddr") - nmc.pexp.expect( + pexp.expect("provider azure detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("found azure interfaces: 2") + pexp.expect(r"interface\[0]: found a matching device with hwaddr") + pexp.expect( r"interface\[0]: (received subnet address|received subnet prefix 20)" ) - nmc.pexp.expect( + pexp.expect( r"interface\[0]: (received subnet address|received subnet prefix 20)" ) - nmc.pexp.expect("get-config: success") - nmc.pexp.expect("meta data received") + pexp.expect("get-config: success") + 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") + 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 azure") - nmc.pexp.expect(pexpect.EOF) + pexp.expect("some changes were applied for provider azure") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_azure") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") # Run nm-cloud-setup for the second time - nmc = Util.cmd_call_pexpect( + pexp = self.ctx.cmd_call_pexpect( ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, [], { @@ -2574,17 +2650,21 @@ class TestNmCloudSetup(unittest.TestCase): }, ) - nmc.pexp.expect("provider azure detected") - nmc.pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") - nmc.pexp.expect("get-config: starting") - nmc.pexp.expect("get-config: success") - nmc.pexp.expect("meta data received") + pexp.expect("provider azure detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("get-config: starting") + pexp.expect("get-config: success") + 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 azure") - nmc.pexp.expect(pexpect.EOF) - - Util.valgrind_check_log(nmc.valgrind_log, "test_azure") + pexp.expect('device needs no update to applied connection "con-eth0"') + pexp.expect("no changes were applied for provider azure") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_azure") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") @cloud_setup_test def test_ec2(self): @@ -2611,7 +2691,7 @@ class TestNmCloudSetup(unittest.TestCase): ) # Run nm-cloud-setup for the first time - nmc = Util.cmd_call_pexpect( + pexp = self.ctx.cmd_call_pexpect( ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, [], { @@ -2621,19 +2701,25 @@ class TestNmCloudSetup(unittest.TestCase): }, ) - nmc.pexp.expect("provider ec2 detected") - nmc.pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") - nmc.pexp.expect("get-config: starting") - nmc.pexp.expect("get-config: success") - nmc.pexp.expect("meta data received") + pexp.expect("provider ec2 detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("get-config: starting") + pexp.expect("get-config: success") + 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") + 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) + pexp.expect("some changes were applied for provider ec2") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_ec2") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") # Run nm-cloud-setup for the second time - nmc = Util.cmd_call_pexpect( + pexp = self.ctx.cmd_call_pexpect( ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, [], { @@ -2643,17 +2729,21 @@ class TestNmCloudSetup(unittest.TestCase): }, ) - nmc.pexp.expect("provider ec2 detected") - nmc.pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") - nmc.pexp.expect("get-config: starting") - nmc.pexp.expect("get-config: success") - nmc.pexp.expect("meta data received") + pexp.expect("provider ec2 detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("get-config: starting") + pexp.expect("get-config: success") + 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") + pexp.expect('device needs no update to applied connection "con-eth0"') + pexp.expect("no changes were applied for provider ec2") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_ec2") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") @cloud_setup_test def test_gcp(self): @@ -2671,7 +2761,7 @@ class TestNmCloudSetup(unittest.TestCase): self._mock_path(gcp_iface + "1/forwarded-ips/0", TestNmCloudSetup._ip2) # Run nm-cloud-setup for the first time - nmc = Util.cmd_call_pexpect( + pexp = self.ctx.cmd_call_pexpect( ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, [], { @@ -2681,20 +2771,26 @@ class TestNmCloudSetup(unittest.TestCase): }, ) - nmc.pexp.expect("provider GCP detected") - nmc.pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") - nmc.pexp.expect("found GCP interfaces: 2") - nmc.pexp.expect(r"GCP interface\[0]: found a requested device with hwaddr") - nmc.pexp.expect("get-config: success") - nmc.pexp.expect("meta data received") + pexp.expect("provider GCP detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("found GCP interfaces: 2") + pexp.expect(r"GCP interface\[0]: found a requested device with hwaddr") + pexp.expect("get-config: success") + 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") + 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 GCP") - nmc.pexp.expect(pexpect.EOF) + pexp.expect("some changes were applied for provider GCP") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_gcp") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") # Run nm-cloud-setup for the second time - nmc = Util.cmd_call_pexpect( + pexp = self.ctx.cmd_call_pexpect( ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, [], { @@ -2704,17 +2800,112 @@ class TestNmCloudSetup(unittest.TestCase): }, ) - nmc.pexp.expect("provider GCP detected") - nmc.pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") - nmc.pexp.expect("get-config: starting") - nmc.pexp.expect("get-config: success") - nmc.pexp.expect("meta data received") + pexp.expect("provider GCP detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("get-config: starting") + pexp.expect("get-config: success") + 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 GCP") - nmc.pexp.expect(pexpect.EOF) + pexp.expect('device needs no update to applied connection "con-eth0"') + pexp.expect("no changes were applied for provider GCP") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_gcp") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") - Util.valgrind_check_log(nmc.valgrind_log, "test_gcp") + @cloud_setup_test + def test_oci(self): + self._mock_devices() + + oci_meta = "/opc/v2/" + self._mock_path(oci_meta + "instance", "{}") + self._mock_path( + oci_meta + "vnics", + """ + [ + { + "macAddr": "%s", + "privateIp": "%s", + "subnetCidrBlock": "172.31.16.0/20", + "virtualRouterIp": "172.31.16.1", + "vlanTag": 810, + "vnicId": "ocid1.vnic.oc1.cz-adamov1.foobarbaz" + }, + { + "macAddr": "%s", + "privateIp": "%s", + "subnetCidrBlock": "172.31.166.0/20", + "virtualRouterIp": "172.31.166.1", + "vlanTag": 700, + "vnicId": "ocid1.vnic.oc1.uk-hogwarts.expelliarmus" + } + ] + """ + % ( + TestNmCloudSetup._mac1, + TestNmCloudSetup._ip1, + TestNmCloudSetup._mac2, + TestNmCloudSetup._ip2, + ), + ) + + # Run nm-cloud-setup for the first time + pexp = self.ctx.cmd_call_pexpect( + ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, + [], + { + "NM_CLOUD_SETUP_OCI_HOST": self.md_url, + "NM_CLOUD_SETUP_LOG": "trace", + "NM_CLOUD_SETUP_OCI": "yes", + }, + ) + + pexp.expect("provider oci detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("get-config: starting") + pexp.expect("get-config: success") + pexp.expect("meta data received") + # One of the devices has no IPv4 configuration to be modified + pexp.expect("device has no suitable applied connection. Skip") + # The other one was lacking an address set it up. + pexp.expect("some changes were applied for provider oci") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_oci") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") + + # Run nm-cloud-setup for the second time + pexp = self.ctx.cmd_call_pexpect( + ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, + [], + { + "NM_CLOUD_SETUP_OCI_HOST": self.md_url, + "NM_CLOUD_SETUP_LOG": "trace", + "NM_CLOUD_SETUP_OCI": "yes", + }, + ) + + pexp.expect("provider oci detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("get-config: starting") + pexp.expect("get-config: success") + pexp.expect("meta data received") + # No changes this time + pexp.expect('device needs no update to applied connection "con-eth0"') + pexp.expect("no changes were applied for provider oci") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_oci") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") ############################################################################### |