diff options
Diffstat (limited to 'clients/tests/test-client.py')
| -rwxr-xr-x | clients/tests/test-client.py | 369 |
1 files changed, 154 insertions, 215 deletions
diff --git a/clients/tests/test-client.py b/clients/tests/test-client.py index 3ab5de31..74225ccf 100755 --- a/clients/tests/test-client.py +++ b/clients/tests/test-client.py @@ -141,15 +141,6 @@ class Util: t = basestring return isinstance(s, t) - @staticmethod - def memoize_nullary(nullary_func): - result = [] - def closure(): - if not result: - result.append(nullary_func()) - return result[0] - return closure - _find_unsafe = re.compile(r'[^\w@%+=:,./-]', re.ASCII if sys.version_info[0] >= 3 else 0).search @@ -244,9 +235,7 @@ class Util: for fmt in [[], ['--pretty'], ['--terse']]: - for color in [[], - ['--color', 'yes']]: - yield mode + fmt + color + yield mode + fmt ############################################################################### @@ -428,39 +417,13 @@ class AsyncProcess(): ############################################################################### +file_list = [] + class NmTestBase(unittest.TestCase): pass class TestNmcli(NmTestBase): - @staticmethod - def _read_expected(filename): - results_expect = [] - content_expect = Util.file_read(filename) - try: - base_idx = 0 - size_prefix = 'size: '.encode('utf8') - while True: - if not content_expect[base_idx:base_idx + 10].startswith(size_prefix): - raise Exception("Unexpected token") - j = base_idx + len(size_prefix) - i = j - if Util.python_has_version(3, 0): - eol = ord('\n') - else: - eol = '\n' - while content_expect[i] != eol: - i += 1 - i = i + 1 + int(content_expect[j:i]) - results_expect.append(content_expect[base_idx:i]) - if len(content_expect) == i: - break - base_idx = i - except Exception as e: - results_expect = None - - return content_expect, results_expect - def call_nmcli_l(self, args, check_on_disk = _DEFAULT_ARG, @@ -589,7 +552,6 @@ class TestNmcli(NmTestBase): env['LIBNM_USE_SESSION_BUS'] = '1' env['LIBNM_USE_NO_UDEV'] = '1' env['TERM'] = 'linux' - env['XDG_CONFIG_HOME'] = PathConfiguration.srcdir() if fatal_warnings is _DEFAULT_ARG or fatal_warnings: env['G_DEBUG'] = 'fatal-warnings' @@ -654,29 +616,56 @@ class TestNmcli(NmTestBase): if expected_returncode is None: self.assertEqual(returncode, -5) - if check_on_disk: - cmd = '$NMCLI %s' % (' '.join([Util.quote(a) for a in args[1:]])), + dirname = PathConfiguration.srcdir() + '/test-client.check-on-disk' + basename = test_name + '.expected' + filename = os.path.abspath(dirname + '/' + basename) - content = ('location: %s\n' % (calling_location)).encode('utf8') + \ - ('cmd: %s\n' % (cmd)).encode('utf8') + \ + if not check_on_disk: + if os.path.exists(filename): + self.fail("The file '%s' exists, although we expect it not to." % (filename)) + return + + file_list.append(basename) + + content_old = Util.file_read(filename) + + content_new = ('location: %s\n' % (calling_location)).encode('utf8') + \ + ('cmd: $NMCLI %s\n' % (' '.join([Util.quote(a) for a in args[1:]]))).encode('utf8') + \ ('lang: %s\n' % (lang)).encode('utf8') + \ - ('returncode: %d\n' % (returncode)).encode('utf8') - if len(stdout) > 0: - content += ('stdout: %d bytes\n>>>\n' % (len(stdout))).encode('utf8') + \ - stdout + \ - '\n<<<\n'.encode('utf8') - if len(stderr) > 0: - content += ('stderr: %d bytes\n>>>\n' % (len(stderr))).encode('utf8') + \ - stderr + \ - '\n<<<\n'.encode('utf8') - content = ('size: %s\n' % (len(content))).encode('utf8') + \ - content - - self._results.append({ - 'test_name' : test_name, - 'ignore_l10n_diff' : ignore_l10n_diff, - 'content' : content, - }) + ('returncode: %d\n' % (returncode)).encode('utf8') + \ + ('stdout: %d bytes\n>>>\n' % (len(stdout))).encode('utf8') + \ + stdout + \ + ('\n<<<\nstderr: %d bytes\n>>>\n' % (len(stderr))).encode('utf8') + \ + stderr + \ + '\n<<<\n'.encode('utf8') + + w = conf.get(ENV_NM_TEST_REGENERATE) + + if content_old is not None: + if content_old == content_new: + return + + if not w: + if ignore_l10n_diff: + self._skip_test_for_l10n_diff.append(test_name) + return + print("\n\n\nThe file '%s' does not have the expected content:" % (filename)) + print("ACTUAL OUTPUT:\n[[%s]]\n" % (content_new)) + print("EXPECT OUTPUT:\n[[%s]]\n" % (content_old)) + 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())) + raise AssertionError("Unexpected output of command, expected %s. Rerun test with NM_TEST_REGENERATE=1 to regenerate files" % (filename)) + else: + if not w: + self.fail("The file '%s' does not exist. Let the test write the file by rerunning with NM_TEST_REGENERATE=1" % (filename)) + + try: + if not os.path.exists(dirname): + os.makedirs(dirname) + 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)) async_job = AsyncProcess(args = args, env = env, @@ -699,94 +688,31 @@ class TestNmcli(NmTestBase): self.async_start() self._async_jobs.pop(0).wait() - def _nm_test_pre(self): + def setUp(self): + if not dbus_session_inited: + self.skipTest("Own D-Bus session for testing is not initialized. Do you have dbus-run-session available?") + if NM is None: + self.skipTest("gi.NM is not available. Did you build with introspection?") + self.srv = NMStubServer(self._testMethodName) self._calling_num = {} self._skip_test_for_l10n_diff = [] self._async_jobs = [] - self._results = [] - - self.srv = NMStubServer(self._testMethodName) - - def _nm_test_post(self): + def tearDown(self): self.async_wait() - self.srv.shutdown() self.srv = None - self._calling_num = None - - results = self._results - self._results = None - - skip_test_for_l10n_diff = self._skip_test_for_l10n_diff - self._skip_test_for_l10n_diff = None - - test_name = self._testMethodName - - filename = os.path.abspath(PathConfiguration.srcdir() + '/test-client.check-on-disk/' + test_name + '.expected') - - regenerate = conf.get(ENV_NM_TEST_REGENERATE) - - content_expect, results_expect = self._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" % (results_expect[i])) - print("EXPECT OUTPUT:\n[[%s]]\n" % (n['content'])) - 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())) - 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())) - self.fail("Unexpected output of command, expected %s. Rerun test with NM_TEST_REGENERATE=1 to regenerate files" % (filename)) - - if regenerate: - content_new = ''.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: + if self._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. - self.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._nm_test_pre() - func(self) - self._nm_test_post() - return f - - def setUp(self): - if not dbus_session_inited: - self.skipTest("Own D-Bus session for testing is not initialized. Do you have dbus-run-session available?") - if NM is None: - self.skipTest("gi.NM is not available. Did you build with introspection?") + msg = "Skipped asserting for localized tests %s. Set NM_TEST_CLIENT_CHECK_L10N=1 to force fail." % (','.join(self._skip_test_for_l10n_diff)) + if Util.python_has_version(3): + # python2 does not suppot skipping the test during tearDown() + self.skipTest(msg) + print(msg + "\n") + self._skip_test_for_l10n_diff = None def init_001(self): self.srv.op_AddObj('WiredDevice', @@ -821,7 +747,6 @@ class TestNmcli(NmTestBase): }, }) - @nm_test def test_001(self): self.call_nmcli_l([]) @@ -835,7 +760,6 @@ class TestNmcli(NmTestBase): for mode in Util.iter_nmcli_output_modes(): self.call_nmcli_l(mode + ['general', 'permissions']) - @nm_test def test_002(self): self.init_001() @@ -858,13 +782,12 @@ class TestNmcli(NmTestBase): self.call_nmcli_l(['c', 's', 'con-1']) - @nm_test def test_003(self): self.init_001() replace_stdout = [] - replace_stdout.append((Util.memoize_nullary(lambda: self.srv.findConnectionUuid('con-xx1')), 'UUID-con-xx1-REPLACED-REPLACED-REPLA')) + replace_stdout.append((lambda: self.srv.findConnectionUuid('con-xx1'), 'UUID-con-xx1-REPLACED-REPLACED-REPLA')) self.call_nmcli(['c', 'add', 'type', 'ethernet', 'ifname', '*', 'con-name', 'con-xx1'], replace_stdout = replace_stdout) @@ -872,7 +795,7 @@ class TestNmcli(NmTestBase): self.call_nmcli_l(['c', 's'], replace_stdout = replace_stdout) - replace_stdout.append((Util.memoize_nullary(lambda: self.srv.findConnectionUuid('ethernet')), 'UUID-ethernet-REPLACED-REPLACED-REPL')) + replace_stdout.append((lambda: self.srv.findConnectionUuid('ethernet'), 'UUID-ethernet-REPLACED-REPLACED-REPL')) self.call_nmcli(['c', 'add', 'type', 'ethernet', 'ifname', '*'], replace_stdout = replace_stdout) @@ -944,29 +867,45 @@ class TestNmcli(NmTestBase): self.async_wait() self.srv.op_ConnectionSetVisible(False, con_id = 'ethernet') - for mode in Util.iter_nmcli_output_modes(): - self.call_nmcli_l(mode + ['-f', 'ALL', 'con'], - replace_stdout = replace_stdout) + self.call_nmcli_l(['-f', 'ALL', 'con'], + replace_stdout = replace_stdout) + + self.call_nmcli_l(['-f', 'UUID,TYPE', 'con'], + replace_stdout = replace_stdout) + + self.call_nmcli_l(['-f', 'UUID,TYPE', '--mode', 'multiline', 'con'], + replace_stdout = replace_stdout) + + self.call_nmcli_l(['-f', 'UUID,TYPE', '--mode', 'multiline', '--terse', 'con'], + replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['-f', 'UUID,TYPE', 'con'], - replace_stdout = replace_stdout) + self.call_nmcli_l(['-f', 'UUID,TYPE', '--mode', 'multiline', '--pretty', 'con'], + replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['con', 's', 'ethernet'], - replace_stdout = replace_stdout) + self.call_nmcli_l(['-f', 'UUID,TYPE', '--mode', 'tabular', 'con'], + replace_stdout = replace_stdout) + + self.call_nmcli_l(['-f', 'UUID,TYPE', '--mode', 'tabular', '--terse', 'con'], + replace_stdout = replace_stdout) + + self.call_nmcli_l(['-f', 'UUID,TYPE', '--mode', 'tabular', '--pretty', 'con'], + replace_stdout = replace_stdout) + + self.call_nmcli_l(['con', 's', 'ethernet'], + replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['c', 's', '/org/freedesktop/NetworkManager/ActiveConnection/1'], - replace_stdout = replace_stdout) + self.call_nmcli_l(['c', 's', '/org/freedesktop/NetworkManager/ActiveConnection/1'], + replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['-f', 'all', 'dev', 'show', 'eth0'], - replace_stdout = replace_stdout) + self.call_nmcli_l(['-f', 'all', 'dev', 'show', 'eth0'], + replace_stdout = replace_stdout) - @nm_test def test_004(self): self.init_001() replace_stdout = [] - replace_stdout.append((Util.memoize_nullary(lambda: self.srv.findConnectionUuid('con-xx1')), 'UUID-con-xx1-REPLACED-REPLACED-REPLA')) + replace_stdout.append((lambda: self.srv.findConnectionUuid('con-xx1'), 'UUID-con-xx1-REPLACED-REPLACED-REPLA')) self.call_nmcli(['c', 'add', 'type', 'wifi', 'ifname', '*', 'ssid', 'foobar', 'con-name', 'con-xx1'], replace_stdout = replace_stdout) @@ -982,7 +921,7 @@ class TestNmcli(NmTestBase): self.async_wait() - replace_stdout.append((Util.memoize_nullary(lambda: self.srv.findConnectionUuid('con-vpn-1')), 'UUID-con-vpn-1-REPLACED-REPLACED-REP')) + replace_stdout.append((lambda: self.srv.findConnectionUuid('con-vpn-1'), 'UUID-con-vpn-1-REPLACED-REPLACED-REP')) self.call_nmcli(['connection', 'add', 'type', 'vpn', 'con-name', 'con-vpn-1', 'ifname', '*', 'vpn-type', 'openvpn', 'vpn.data', 'key1 = val1, key2 = val2, key3=val3'], replace_stdout = replace_stdout) @@ -1008,72 +947,59 @@ class TestNmcli(NmTestBase): 'VpnState', dbus.UInt32(NM.VpnConnectionState.ACTIVATED)) - for mode in Util.iter_nmcli_output_modes(): - - self.call_nmcli_l(mode + ['con', 's', 'con-vpn-1'], - replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['con', 's', 'con-vpn-1'], - replace_stdout = replace_stdout) - - self.call_nmcli_l(mode + ['-f', 'ALL', 'con', 's', 'con-vpn-1'], - replace_stdout = replace_stdout) - - # This only filters 'vpn' settings from the connection profile. - # Contrary to '-f GENERAL' below, it does not show the properties of - # the activated VPN connection. This is a nmcli bug. - self.call_nmcli_l(mode + ['-f', 'VPN', 'con', 's', 'con-vpn-1'], - replace_stdout = replace_stdout) - - self.call_nmcli_l(mode + ['-f', 'GENERAL', 'con', 's', 'con-vpn-1'], - replace_stdout = replace_stdout) - - self.call_nmcli_l(mode + ['dev', 's'], - replace_stdout = replace_stdout) + self.call_nmcli_l(['con', 's', 'con-vpn-1'], + replace_stdout = replace_stdout) + self.call_nmcli_l(['-t', 'con', 's', 'con-vpn-1'], + replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['-f', 'all', 'dev', 'status'], - replace_stdout = replace_stdout) + self.call_nmcli_l(['-f', 'ALL', 'con', 's', 'con-vpn-1'], + replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['dev', 'show'], - replace_stdout = replace_stdout) + # This only filters 'vpn' settings from the connection profile. + # Contrary to '-f GENERAL' below, it does not show the properties of + # the activated VPN connection. This is a nmcli bug. + self.call_nmcli_l(['-f', 'VPN', 'con', 's', 'con-vpn-1'], + replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['-f', 'all', 'dev', 'show'], - replace_stdout = replace_stdout) + self.call_nmcli_l(['-f', 'GENERAL', 'con', 's', 'con-vpn-1'], + replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['dev', 'show', 'wlan0'], - replace_stdout = replace_stdout) + self.call_nmcli_l(['dev', 'show', 'wlan0'], + replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['-f', 'all', 'dev', 'show', 'wlan0'], - replace_stdout = replace_stdout) + self.call_nmcli_l(['-f', 'all', 'dev', 'show', 'wlan0'], + replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['-f', 'GENERAL,GENERAL.HWADDR,WIFI-PROPERTIES', 'dev', 'show', 'wlan0'], - replace_stdout = replace_stdout) + self.call_nmcli_l(['-f', 'GENERAL,GENERAL.HWADDR,WIFI-PROPERTIES', 'dev', 'show', 'wlan0'], + replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['-f', 'GENERAL,GENERAL.HWADDR,WIFI-PROPERTIES', 'dev', 'show', 'wlan0'], - replace_stdout = replace_stdout) + self.call_nmcli_l(['-f', 'GENERAL,GENERAL.HWADDR,WIFI-PROPERTIES', '-t', 'dev', 'show', 'wlan0'], + replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['-f', 'DEVICE,TYPE,DBUS-PATH', 'dev'], - replace_stdout = replace_stdout) + self.call_nmcli_l(['-f', 'DEVICE,TYPE,DBUS-PATH', 'dev'], + replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['-f', 'ALL', 'device', 'wifi', 'list' ], - replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['-f', 'COMMON', 'device', 'wifi', 'list' ], - replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['-f', 'NAME,SSID,SSID-HEX,BSSID,MODE,CHAN,FREQ,RATE,SIGNAL,BARS,SECURITY,WPA-FLAGS,RSN-FLAGS,DEVICE,ACTIVE,IN-USE,DBUS-PATH', - 'device', 'wifi', 'list'], - replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['-f', 'ALL', 'device', 'wifi', 'list', 'bssid', 'C0:E2:BE:E8:EF:B6'], - replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['-f', 'COMMON', 'device', 'wifi', 'list', 'bssid', 'C0:E2:BE:E8:EF:B6'], - replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['-f', 'NAME,SSID,SSID-HEX,BSSID,MODE,CHAN,FREQ,RATE,SIGNAL,BARS,SECURITY,WPA-FLAGS,RSN-FLAGS,DEVICE,ACTIVE,IN-USE,DBUS-PATH', - 'device', 'wifi', 'list', 'bssid', 'C0:E2:BE:E8:EF:B6'], - replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['-f', 'ALL', 'device', 'show', 'wlan0' ], - replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['-f', 'COMMON', 'device', 'show', 'wlan0' ], - replace_stdout = replace_stdout) - self.call_nmcli_l(mode + ['-f', 'GENERAL,CAPABILITIES,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,WIMAX-PROPERTIES,NSP,IP4,DHCP4,IP6,DHCP6,BOND,TEAM,BRIDGE,VLAN,BLUETOOTH,CONNECTIONS', 'device', 'show', 'wlan0' ], - replace_stdout = replace_stdout) + for mode in Util.iter_nmcli_output_modes(): + self.call_nmcli_l(mode + ['-f', 'ALL', 'device', 'wifi', 'list' ], + replace_stdout = replace_stdout) + self.call_nmcli_l(mode + ['-f', 'COMMON', 'device', 'wifi', 'list' ], + replace_stdout = replace_stdout) + self.call_nmcli_l(mode + ['-f', 'NAME,SSID,SSID-HEX,BSSID,MODE,CHAN,FREQ,RATE,SIGNAL,BARS,SECURITY,WPA-FLAGS,RSN-FLAGS,DEVICE,ACTIVE,IN-USE,DBUS-PATH', + 'device', 'wifi', 'list'], + replace_stdout = replace_stdout) + self.call_nmcli_l(mode + ['-f', 'ALL', 'device', 'wifi', 'list', 'bssid', 'C0:E2:BE:E8:EF:B6'], + replace_stdout = replace_stdout) + self.call_nmcli_l(mode + ['-f', 'COMMON', 'device', 'wifi', 'list', 'bssid', 'C0:E2:BE:E8:EF:B6'], + replace_stdout = replace_stdout) + self.call_nmcli_l(mode + ['-f', 'NAME,SSID,SSID-HEX,BSSID,MODE,CHAN,FREQ,RATE,SIGNAL,BARS,SECURITY,WPA-FLAGS,RSN-FLAGS,DEVICE,ACTIVE,IN-USE,DBUS-PATH', + 'device', 'wifi', 'list', 'bssid', 'C0:E2:BE:E8:EF:B6'], + replace_stdout = replace_stdout) + self.call_nmcli_l(mode + ['-f', 'ALL', 'device', 'show', 'wlan0' ], + replace_stdout = replace_stdout) + self.call_nmcli_l(mode + ['-f', 'COMMON', 'device', 'show', 'wlan0' ], + replace_stdout = replace_stdout) + self.call_nmcli_l(mode + ['-f', 'GENERAL,CAPABILITIES,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,WIMAX-PROPERTIES,NSP,IP4,DHCP4,IP6,DHCP6,BOND,TEAM,BRIDGE,VLAN,BLUETOOTH,CONNECTIONS', 'device', 'show', 'wlan0' ], + replace_stdout = replace_stdout) ############################################################################### @@ -1119,6 +1045,19 @@ def main(): r = unittest.main(exit = False) + if conf.get(ENV_NM_TEST_REGENERATE): + make_filename = PathConfiguration.srcdir() + '/test-client.check-on-disk/Makefile.am' + s_new = '# generated with `NM_TEST_REGENERATE=1 make check`\n' + \ + '# See howto in "' + PathConfiguration.canonical_script_filename() + '"\n' + \ + '\n' + \ + 'clients_tests_expected_files = \\\n' + \ + ''.join([('\tclients/tests/test-client.check-on-disk/%s \\\n' % f) for f in sorted(file_list)]) + \ + '\t$(NULL)\n' + s_new = s_new.encode('utf-8') + if s_new != Util.file_read(make_filename): + with open(make_filename, 'wb') as f: + f.write(s_new) + sys.exit(not r.result.wasSuccessful()) if __name__ == '__main__': |