#!/usr/bin/python3 -cimport os, sys; os.execv(os.path.dirname(sys.argv[1]) + "/../common/pywrap", sys.argv)import osimport testlibEXAMPLES_DIR = os.path.join(os.path.dirname(testlib.TEST_DIR), "examples")@testlib.skipBeiboot("no local overrides/config in beiboot mode")@testlib.nondestructiveclass TestPinger(testlib.MachineCase):def setUp(self):super().setUp()self.restore_dir("/home/admin")self.machine.execute("mkdir -p ~admin/.local/share/cockpit")self.machine.upload([os.path.join(EXAMPLES_DIR, "pinger")], "/home/admin/.local/share/cockpit/")def testBasic(self):b = self.browserself.login_and_go("/pinger/ping")b.set_val("#address", "127.0.0.1")b.click("button#ping")b.wait_in_text("#result", "success")b.wait_in_text("#output", "--- 127.0.0.1 ping statistics")def testExtend(self):"""This is example test should set summaryand it also setup description text"""self.testBasic()@testlib.skipBeiboot("no local overrides/config in beiboot mode")@testlib.nondestructiveclass TestXHRProxy(testlib.MachineCase):def setUp(self):super().setUp()self.restore_dir("/home/admin")self.machine.execute("mkdir -p ~admin/.local/share/cockpit")self.machine.upload([os.path.join(EXAMPLES_DIR, "xhr-proxy")], "/home/admin/.local/share/cockpit/")@testlib.skipOstree("No Python installed")def testBasic(self):m = self.machineb = self.browser# set up served directoryhttpdir = self.vm_tmpdir + "/root"m.write(f"{httpdir}/hello.txt", "world\n")# start webserverpid = m.spawn(f"cd {httpdir}; exec python3 -m http.server 12345", "httpserver")self.addCleanup(m.execute, "kill %i" % pid)self.machine.wait_for_cockpit_running(port=12345) # wait for changelog HTTP server to start upself.login_and_go("/xhr-proxy/xhrproxy")# directory indexb.set_val("#address", "http://localhost:12345/")b.click("#get")b.wait_text("#result", "200")b.wait_in_text("#output", "Directory listing")b.wait_in_text("#output", "hello.txt")# specific fileb.set_val("#address", "http://localhost:12345/hello.txt")b.click("#get")b.wait_text("#result", "200")b.wait_text("#output", "world\n")# nonexisting pathb.set_val("#address", "http://localhost:12345/nosuchfile")b.click("#get")b.wait_text("#result", "404")b.wait_in_text("#output", "File not found")@testlib.skipBeiboot("no local overrides/config in beiboot mode")@testlib.nondestructiveclass TestLongRunning(testlib.MachineCase):def setUp(self):super().setUp()m = self.machineself.restore_dir("/home/admin")m.execute("mkdir -p ~admin/.local/share/cockpit")m.upload([os.path.join(EXAMPLES_DIR, "long-running-process")], "/home/admin/.local/share/cockpit/")# clean up after test failuresself.addCleanup(m.execute, "systemctl stop cockpit-longrunning.service 2>/dev/null && systemctl reset-failed cockpit-longrunning.service || true")# sometimes fails with: unexpected failure of GetUnit(cockpit-longrunning.service): Not permitted to perform this actiondef testBasic(self):b = self.browserm = self.machineself.login_and_go("/long-running-process")self.assertEqual(m.execute("systemctl is-active cockpit-longrunning.service || true").strip(), "inactive")b.wait_text("#state", "cockpit-longrunning.service stopped")b.wait_text("#output", "")# run a command that the test can control synchronouslyack_file = self.vm_tmpdir + "/ack_a"b.set_val("#command", f"date; echo STEP_A; until [ -e {ack_file} ]; do sleep 1; done; echo STEP_B; sleep 1; echo DONE")b.wait_text("button#run", "Start")b.click("button#run")b.wait_text("#state", "cockpit-longrunning.service running")b.wait_in_text("#output", "\nSTEP_A\n")self.assertNotIn("\nSTEP_B", b.text("#output"))self.assertEqual(m.execute("systemctl is-active cockpit-longrunning.service || true").strip(), "activating")# reattaches in new sessionb.logout()b.login_and_go("/long-running-process")b.wait_text("#state", "cockpit-longrunning.service running")b.wait_text("button#run", "Terminate")b.wait_in_text("#output", "\nSTEP_A\n")self.assertEqual(m.execute("systemctl is-active cockpit-longrunning.service || true").strip(), "activating")# resume processm.execute(f"mkdir -p {self.vm_tmpdir}; touch {ack_file}")b.wait_in_text("#output", "\nSTEP_B\n")# wait for completionb.wait_in_text("#output", "\nDONE\n")b.wait_text("#state", "cockpit-longrunning.service stopped")self.assertEqual(m.execute("systemctl is-active cockpit-longrunning.service || true").strip(), "inactive")# in next session it is back at "not running"b.logout()b.login_and_go("/long-running-process")b.wait_text("#state", "cockpit-longrunning.service stopped")b.wait_text("#output", "")b.wait_text("button#run", "Start")# failing processm.execute("rm -f " + ack_file)b.set_val("#command", f"date; echo BREAK_A; until [ -e {ack_file} ]; do sleep 1; done; false; echo NOTME")b.click("button#run")b.wait_text("#state", "cockpit-longrunning.service running")b.wait_in_text("#output", "\nBREAK_A\n")m.execute("touch " + ack_file)b.wait_text("#state", "cockpit-longrunning.service failed")b.wait_in_text("#output", "cockpit-longrunning.service: Main process exited, code=exited, status=1/FAILURE")out = b.text("#output")self.assertNotIn("\nNOTME", out)# does not contain previous logsself.assertNotIn("STEP_B", out)b.wait_text("button#run", "Reset")# failing state gets picked up on page reconnectb.logout()b.login_and_go("/long-running-process")b.wait_text("#state", "cockpit-longrunning.service failed")b.wait_in_text("#output", "cockpit-longrunning.service: Main process exited, code=exited, status=1/FAILURE")out = b.text("#output")self.assertIn("\nBREAK_A\n", out)self.assertNotIn("\nNOTME", out)b.wait_text("button#run", "Reset")# resetb.click("button#run")b.wait_text("#state", "cockpit-longrunning.service stopped")# cancel long-running commandb.set_val("#command", "for i in $(seq 100); do echo $FOOBAR$i; sleep 1; done")# ensure we can set systemd-run argumentsb.set_val("#sysrun-args", '--setenv=FOOBAR=LONG')b.wait_text("button#run", "Start")b.click("button#run")b.wait_text("#state", "cockpit-longrunning.service running")b.wait_text("button#run", "Terminate")b.wait_in_text("#output", "\nLONG2\n")b.click("button#run")# terminates cleanlyb.wait_text("#state", "cockpit-longrunning.service stopped")self.assertEqual(m.execute("systemctl is-active cockpit-longrunning.service || true").strip(), "inactive")b.wait_in_text("#output", "\nLONG2\n")self.assertNotIn("\nLONG30\n", b.text("#output"))if __name__ == '__main__':testlib.test_main()