From 78ca8545902252f49b20aa22550e888151345f04 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Thu, 25 Apr 2024 08:45:15 +0200 Subject: [PATCH] test: Drop obsolete compat test cases for RHEL/CentOS 7 On June 30, CentOS 7 is EOL and RHEL 7 reaches end-of-maintenance [1]. We haven't changed anything on our rhel-7.9 branch in years, we can put these images to rest. This also means that we can stop supporting the old "implicit superuser" backwards compatibility, as all supported OSes now use the explicit dialog. Drop the various TestSuperuserOld* tests. Also drop TestCentos7 -- we already have a TestRHEL8 for testing connectivity to the C bridge. Drop the `wait_popdown()` testlib API. It's not being used anywhere any more, so vulture complains. External projects don't use it either, and it's too trivial to keep around. [1] https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux/rhel-7-end-of-maintenance --- test/common/testlib.py | 9 +- test/verify/check-shell-multi-os | 127 +-------------- test/verify/check-superuser | 272 ------------------------------- 3 files changed, 6 insertions(+), 402 deletions(-) diff --git a/test/common/testlib.py b/test/common/testlib.py index f4896e9b1793..01f763cd99a7 100644 --- a/test/common/testlib.py +++ b/test/common/testlib.py @@ -735,13 +735,6 @@ def wait_popup(self, elem_id: str) -> None: """ self.wait_visible('#' + elem_id) - def wait_popdown(self, elem_id: str) -> None: - """Wait for a popup to close. - - :param id: the 'id' attribute of the popup. - """ - self.wait_not_visible('#' + elem_id) - def wait_language(self, lang: str) -> None: parts = lang.split("-") code_1 = parts[0] @@ -1472,7 +1465,7 @@ def is_devel_build(self) -> bool: return os.environ.get('NODE_ENV') == 'development' def is_pybridge(self) -> bool: - # some tests start e.g. centos-7 as first machine, bridge may not exist there + # some tests start e.g. centos-8 as first machine, bridge may not exist there return any('python' in m.execute('head -c 30 /usr/bin/cockpit-bridge || true') for m in self.machines.values()) def disable_preload(self, *packages: str, machine: testvm.Machine | None = None) -> None: diff --git a/test/verify/check-shell-multi-os b/test/verify/check-shell-multi-os index 08828b9f0502..c5105389eacd 100755 --- a/test/verify/check-shell-multi-os +++ b/test/verify/check-shell-multi-os @@ -42,118 +42,6 @@ def add_machine(b, address, password): b.wait_not_present('#hosts_setup_server_dialog') -def wait_stock_addresses(b, expected): - b.wait_js_func( - """(function(expected) { - var nodes = document.querySelectorAll('#dashboard-hosts .list-group-item'); - var addresses = Array.prototype.map.call(nodes, function(e) { - return e.getAttribute("data-address"); - }); - return expected.sort().toString() == addresses.sort().toString(); - })""", expected) - - -def add_stock_machine(b, address, password): - b.click('#dashboard-add') - b.wait_popup('dashboard_setup_server_dialog') - b.set_input_text('#add-machine-address', address) - - b.click('#dashboard_setup_server_dialog button:contains(Add)') - b.wait_in_text('#dashboard_setup_server_dialog', "Fingerprint") - b.click('#dashboard_setup_server_dialog button:contains(Connect)') - if password: - b.wait_in_text('#dashboard_setup_server_dialog', "Unable to log in") - b.set_input_text('#login-custom-password', password) - b.click('#dashboard_setup_server_dialog button:contains(Log in)') - b.wait_popdown('dashboard_setup_server_dialog') - - -@testlib.skipDistroPackage() -class TestCentos7(testlib.MachineCase): - provision = { - "0": {"address": "10.111.113.1/20", "memory_mb": 512}, - "centos-7": {"address": "10.111.113.5/20", "image": "centos-7", "memory_mb": 512} - } - - def check_spawn(self, b, address): - # HACK: Firefox cannot do `cockpit.spawn` as it returns promise - # Firefox can wait for promise to resolve, but then cannot get value from it - if b.cdp.browser.name == "firefox": - return - result = b.call_js_func("""(function(address) { - return cockpit.spawn(['echo', 'hi'], { host: address }); - })""", address) - self.assertEqual(result, "hi\n") - - def check_dbus(self, b, address): - # HACK: Firefox cannot do `cockpit.dbus.proxy.call` as it returns promise - if b.cdp.browser.name == "firefox": - return - b.call_js_func("""(function(address) { - return cockpit.dbus("org.freedesktop.DBus", { host: address }) - .proxy("org.freedesktop.DBus", "/").call("GetId"); - })""", address) - - @testlib.todoPybridgeRHEL8() - def test(self): - dev_m = self.machine - dev_b = self.browser - - self.allow_hostkey_messages() - - self.login_and_go() - dev_b.click("#hosts-sel button") - dev_addresses = ["localhost"] - wait_addresses(dev_b, dev_addresses) - - stock_m = self.machines['centos-7'] - stock_m.execute("firewall-cmd --add-service cockpit") - stock_m.start_cockpit() - - # Wait for connectivity between the two - testlib.wait(lambda: stock_m.execute("ip addr >&2 && ping -q -w5 -c5 10.111.113.1")) - testlib.wait(lambda: dev_m.execute("ip addr >&2 && ping -q -w5 -c5 10.111.113.5")) - - stock_m.execute("hostnamectl set-hostname stock") - stock_b = self.new_browser(stock_m) - - stock_b.login_and_go("/dashboard", legacy_authorized=True) - wait_stock_addresses(stock_b, ["localhost"]) - - add_stock_machine(stock_b, "10.111.113.1", password=None) - wait_stock_addresses(stock_b, ["localhost", "10.111.113.1"]) - - add_machine(dev_b, "10.111.113.5", password="foobar") - dev_addresses.append("10.111.113.5") - wait_addresses(dev_b, dev_addresses) - - stock_b.switch_to_top() - self.check_dbus(stock_b, "10.111.113.1") - self.check_dbus(dev_b, "10.111.113.5") - - self.check_spawn(stock_b, "10.111.113.1") - self.check_spawn(dev_b, "10.111.113.5") - - dev_b.go("/@10.111.113.5/network") - dev_b.wait_visible("iframe.container-frame[name='cockpit1:10.111.113.5/network'][src$='/network/index.html#/']") - - dev_b.go("/@10.111.113.5/storage") - dev_b.wait_visible("iframe.container-frame[name='cockpit1:10.111.113.5/storage'][src$='/storage/index.html#/']") - - dev_b.switch_to_top() - dev_b.go("/@10.111.113.5/users") - dev_b.wait_visible("iframe.container-frame[name='cockpit1:10.111.113.5/users'][src$='/users/index.html#/']") - - stock_b.go("/@10.111.113.1/system") - stock_b.wait_visible("iframe.container-frame[name='cockpit1:10.111.113.1/system'][data-loaded]") - stock_b.switch_to_frame('cockpit1:10.111.113.1/system') - stock_b.wait_text_not("#system_information_hardware_text", "") - - # Messages from previous versions of cockpit - self.allow_journal_messages(".*pam_authenticate failed: Authentication failure") - self.allow_restart_journal_messages() - - @testlib.skipDistroPackage() class TestRHEL8(testlib.MachineCase): provision = { @@ -197,11 +85,11 @@ class TestRHEL8(testlib.MachineCase): class TestMultiOSDirect(testlib.MachineCase): provision = { "0": {"address": "10.111.113.1/20", "memory_mb": 512}, - "centos-7": {"address": "10.111.113.5/20", "image": "centos-7", "memory_mb": 512} + "stock": {"address": "10.111.113.5/20", "image": "centos-8-stream", "memory_mb": 512} } @testlib.todoPybridgeRHEL8() - def testCentos7Direct(self): + def testCentos8Direct(self): b = self.browser self.allow_hostkey_messages() @@ -212,7 +100,7 @@ class TestMultiOSDirect(testlib.MachineCase): dev_addresses = ["localhost"] wait_addresses(b, dev_addresses) - stock_m = self.machines['centos-7'] + stock_m = self.machines['stock'] stock_m.execute("hostnamectl set-hostname stock") add_machine(b, "10.111.113.5", password="foobar") @@ -222,12 +110,7 @@ class TestMultiOSDirect(testlib.MachineCase): # Access stock directly from dev b.open("/=10.111.113.5") - b.wait_visible("#login") - b.wait_not_visible("#badge") - b.wait_not_visible("#brand") - b.set_input_text("#login-user-input", "admin") - b.set_input_text("#login-password-input", "foobar") - b.click('#login-button') + b.try_login(superuser=False) b.wait_visible("#hostkey-group") b.wait_in_text("#hostkey-message-1", "You are connecting to 10.111.113.5 for the first time.") b.click('#login-button') @@ -237,7 +120,7 @@ class TestMultiOSDirect(testlib.MachineCase): b.wait_visible("iframe.container-frame[name='cockpit1:localhost/system']") b.switch_to_frame("cockpit1:localhost/system") b.wait_visible("body") - b.wait_in_text('#system_information_hostname_button', "stock") + b.wait_in_text('#system_information_hostname_text', "stock") b.switch_to_top() b.wait_js_cond('window.location.pathname == "/=10.111.113.5/system"') diff --git a/test/verify/check-superuser b/test/verify/check-superuser index a796453f15e6..60f3fbaedb5e 100755 --- a/test/verify/check-superuser +++ b/test/verify/check-superuser @@ -22,14 +22,6 @@ import time import testlib -def allow_old_cockpit_ws_messages(test): - # noisy debug message from old cockpit-ws/polkit - test.allow_journal_messages("logged in user session", - "New connection to session from.*", - "pam_unix(polkit-1:session): session opened for user root by .*uid=.*", - "admin: Executing command .*COMMAND=.*cockpit-bridge --privileged.*") - - @testlib.nondestructive @testlib.skipDistroPackage() class TestSuperuser(testlib.MachineCase): @@ -407,151 +399,6 @@ session include system-auth b.wait_not_present(".pf-v5-c-alert:contains('Web console is running in limited access mode.')") -@testlib.skipDistroPackage() -class TestSuperuserOldShell(testlib.MachineCase): - provision = { - "machine1": {"address": "10.111.113.1/20", "memory_mb": 512}, - "machine2": {"address": "10.111.113.2/20", "image": "centos-7", "memory_mb": 512}, - } - - def test(self): - b = self.browser - m = self.machine - - m.start_cockpit() - - # Use m1 to login into m2 - b.open("/") - b.wait_visible("#login") - b.set_val("#login-user-input", "admin") - b.set_val("#login-password-input", "foobar") - b.click("#show-other-login-options") - b.wait_visible("#server-group") - b.set_val("#server-field", "10.111.113.2") - b.click('#login-button') - b.wait_in_text("#server-name", "10.111.113.2") - b.wait_visible("#hostkey-group") - b.wait_in_text("#hostkey-message-1", "You are connecting to 10.111.113.2 for the first time.") - b.click('#login-button') - b.wait_visible('#content') - - # The old shell should have gotten the password from cockpit-ws and it should work - b.enter_page("/system") - b.click("#shutdown-group > button:contains('Restart')") - b.wait_popup("shutdown-dialog") - b.click("#shutdown-dialog button:contains('Restart')") - b.wait_popdown("shutdown-dialog") - - -@testlib.skipImage("TODO: broken on Arch Linux", "arch") -@testlib.skipDistroPackage() -class TestSuperuserOldWebserver(testlib.MachineCase): - provision = { - "machine1": {"address": "10.111.113.1/20", "image": "centos-7", "memory_mb": 512}, - "machine2": {"address": "10.111.113.2/20", "memory_mb": 512}, - } - - def test(self): - b = self.browser - m = self.machine - - allow_old_cockpit_ws_messages(self) - - m.execute("firewall-cmd --add-service cockpit") - m.start_cockpit() - - # Use m1 to login into m2 - b.open("/") - b.wait_visible("#login") - b.set_val("#login-user-input", "admin") - b.set_val("#login-password-input", "foobar") - b.set_checked('#authorized-input', val=True) - b.click("#show-other-login-options") - b.wait_visible("#server-group") - b.set_val("#server-field", "10.111.113.2") - b.click('#login-button') - b.wait_in_text("#server-name", "10.111.113.2") - b.wait_in_text("#conversation-prompt", "Fingerprint") - b.wait_in_text("#conversation-message", "Do you want to proceed this time?") - b.click('#login-button') - b.wait_visible('#content') - - if not self.is_pybridge(): - # The C bridge will recognize that it is being started by - # a old webserver (or old bridge) and will start "any" - # privileged bridge during startup. - b.check_superuser_indicator("Administrative access") - b.go("/playground/test") - b.enter_page("/playground/test") - b.click(".super-channel button") - b.wait_in_text(".super-channel span", 'result: ') - self.assertIn('result: uid=0', b.text(".super-channel span")) - - else: - # The Python bridge will not start any privileged bridge - # if not explicitly told, and a old webserver (or old - # bridge) does not tell it anything. - b.check_superuser_indicator("Limited access") - b.go("/playground/test") - b.enter_page("/playground/test") - b.click(".super-channel button") - b.wait_in_text(".super-channel span", 'access-denied') - - b.become_superuser() - b.go("/playground/test") - b.enter_page("/playground/test") - b.click(".super-channel button") - b.wait_in_text(".super-channel span", 'result: ') - self.assertIn('result: uid=0', b.text(".super-channel span")) - - def testNotAuth(self): - b = self.browser - m = self.machine - - allow_old_cockpit_ws_messages(self) - - m.execute("firewall-cmd --add-service cockpit") - m.start_cockpit() - - # Use m1 to login into m2, but don't reuse the password - b.open("/") - b.wait_visible("#login") - b.set_val("#login-user-input", "admin") - b.set_val("#login-password-input", "foobar") - b.set_checked('#authorized-input', val=False) - b.click("#show-other-login-options") - b.wait_visible("#server-group") - b.set_val("#server-field", "10.111.113.2") - b.click('#login-button') - b.wait_in_text("#server-name", "10.111.113.2") - b.wait_in_text("#conversation-prompt", "Fingerprint") - b.wait_in_text("#conversation-message", "Do you want to proceed this time?") - b.click('#login-button') - b.wait_visible('#content') - - # We should not have gotten the password from the old - # cockpit-ws, but we can get it back. - - b.check_superuser_indicator("Limited access") - b.go("/playground/test") - b.enter_page("/playground/test") - b.click(".super-channel button") - b.wait_in_text(".super-channel span", 'access-denied') - - b.switch_to_top() - b.open_superuser_dialog() - b.wait_in_text(".pf-v5-c-modal-box:contains('Switch to administrative access')", "Password for admin:") - b.set_input_text(".pf-v5-c-modal-box:contains('Switch to administrative access') input", "foobar") - b.click(".pf-v5-c-modal-box button:contains('Authenticate')") - b.wait_not_present(".pf-v5-c-modal-box:contains('Switch to administrative access')") - b.check_superuser_indicator("Administrative access") - b.go("/playground/test") - b.enter_page("/playground/test") - b.click(".super-channel button") - b.wait_in_text(".super-channel span", 'result: ') - self.assertIn('result: uid=0', b.text(".super-channel span")) - - @testlib.skipDistroPackage() class TestSuperuserDashboard(testlib.MachineCase): provision = { @@ -629,124 +476,5 @@ class TestSuperuserDashboard(testlib.MachineCase): self.allow_hostkey_messages() -@testlib.skipDistroPackage() -class TestSuperuserOldDashboard(testlib.MachineCase): - provision = { - "machine1": {"address": "10.111.113.1/20", "image": "centos-7", "memory_mb": 512}, - "machine2": {"address": "10.111.113.2/20", "memory_mb": 512}, - } - - def test(self): - b = self.browser - m = self.machines["machine1"] - - allow_old_cockpit_ws_messages(self) - self.allow_hostkey_messages() - self.setup_provisioned_hosts() - - m.execute("firewall-cmd --add-service cockpit") - m.start_cockpit() - - # Log into m1 and add m2 - b.open("/") - b.wait_visible("#login") - b.set_val("#login-user-input", "admin") - b.set_val("#login-password-input", "foobar") - b.set_checked('#authorized-input', val=True) - b.click('#login-button') - b.wait_visible('#content') - - b.go("/@10.111.113.2") - b.click('#machine-troubleshoot') - b.wait_popup('troubleshoot-dialog') - b.click('#troubleshoot-dialog button:contains("Add")') - b.wait_in_text('#troubleshoot-dialog', "Fingerprint") - b.click('#troubleshoot-dialog button:contains("Connect")') - b.wait_popdown('troubleshoot-dialog') - - # There should be a superuser button in the Overview of machine2 - - def get_admin(): - b.go("/@10.111.113.2") - b.enter_page("/system", host="10.111.113.2") - b.click(".ct-overview-header-actions button:contains('Limited access')") - b.wait_in_text(".pf-v5-c-modal-box:contains('Switch to administrative access')", "Password for admin:") - b.set_input_text(".pf-v5-c-modal-box:contains('Switch to administrative access') input", "foobar") - b.click(".pf-v5-c-modal-box button:contains('Authenticate')") - b.wait_not_present(".pf-v5-c-modal-box:contains('Switch to administrative access')") - b.wait_visible(".ct-overview-header-actions button:contains('Administrative access')") - b.go("/@10.111.113.2/playground/test") - b.enter_page("/playground/test", host="10.111.113.2") - b.click(".super-channel button") - b.wait_in_text(".super-channel span", 'result: ') - self.assertIn('result: uid=0', b.text(".super-channel span")) - - def drop_admin(): - b.go("/@10.111.113.2") - b.enter_page("/system", host="10.111.113.2") - b.click(".ct-overview-header-actions button:contains('Administrative access')") - b.click(".pf-v5-c-modal-box:contains('Switch to limited access') button:contains('Limit access')") - b.wait_not_present(".pf-v5-c-modal-box:contains('Switch to limited access')") - b.wait_visible(".ct-overview-header-actions button:contains('Limited access')") - b.go("/@10.111.113.2/playground/test") - b.enter_page("/playground/test", host="10.111.113.2") - b.click(".super-channel button") - b.wait_in_text(".super-channel span", 'access-denied') - - if not self.is_pybridge(): - # The C bridge will recognize that it is being started by - # a old bridge (or old webserver) and will start "any" - # privileged bridge during startup. So we have admin at - # this point. - # - drop_admin() - get_admin() - - else: - # The Python bridge will not start any privileged bridge - # if not explicitly told, and a old bridge (or old - # webserver) does not tell it anything. So we don't have - # admin at this point. - # - get_admin() - drop_admin() - - -@testlib.skipDistroPackage() -class TestSuperuserDashboardOldMachine(testlib.MachineCase): - provision = { - "machine1": {"address": "10.111.113.1/20"}, - "machine2": {"address": "10.111.113.2/20", "image": "centos-7"}, - } - - @testlib.todoPybridgeRHEL8() - def test(self): - b = self.browser - - self.setup_provisioned_hosts() - self.login_and_go() - b.go("/@10.111.113.2") - b.click('#machine-troubleshoot') - b.wait_visible('#hosts_setup_server_dialog') - b.click('#hosts_setup_server_dialog button:contains("Add")') - b.wait_in_text('#hosts_setup_server_dialog', "You are connecting to 10.111.113.2 for the first time.") - b.click('#hosts_setup_server_dialog button.pf-m-primary') - b.wait_in_text('#hosts_setup_server_dialog', "Unable to log in") - b.set_input_text("#login-custom-password", "foobar") - b.click('#hosts_setup_server_dialog button:contains("Log in")') - b.wait_not_present('#hosts_setup_server_dialog') - - # Since user and password are the same on machine2, we should - # have gotten admin rights. - - b.enter_page("/system", host="10.111.113.2") - b.click("#shutdown-group > button:contains('Restart')") - b.wait_popup("shutdown-dialog") - b.click("#shutdown-dialog button:contains('Restart')") - b.wait_popdown("shutdown-dialog") - - self.allow_hostkey_messages() - - if __name__ == '__main__': testlib.test_main()