-
Notifications
You must be signed in to change notification settings - Fork 354
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Start Firefox before Anaconda on Live
The execution time between Gnome Initial Setup and Anaconda is quite big we need to reduce it by moving FF execution sooner before Anaconda is executed. Time to show Firefox window based on my measurements on VM with 2GB RAM and 4vCPUs: Original execution time: 13 seconds With this commit: less than 6 seconds If we want to reduce this time even more we need to do that in Firefox or Gnome Shell (Gnome Initial Setup environment) somehow. Resolves: rhbz#2236438
- Loading branch information
1 parent
86fb8a9
commit 5b56da9
Showing
4 changed files
with
272 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
# | ||
# Copyright (C) 2023 Red Hat, Inc. | ||
# | ||
# This copyrighted material is made available to anyone wishing to use, | ||
# modify, copy, or redistribute it subject to the terms and conditions of | ||
# the GNU General Public License v.2, or (at your option) any later version. | ||
# This program is distributed in the hope that it will be useful, but WITHOUT | ||
# ANY WARRANTY expressed or implied, including the implied warranties of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | ||
# Public License for more details. You should have received a copy of the | ||
# GNU General Public License along with this program; if not, write to the | ||
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the | ||
# source code or documentation are not subject to the GNU General Public | ||
# License and may only be used or replicated with the express permission of | ||
# Red Hat, Inc. | ||
# | ||
import unittest | ||
import pytest | ||
import tempfile | ||
|
||
from meh.ui.text import TextIntf | ||
|
||
from pyanaconda.ui.webui import CockpitUserInterface, FIREFOX_THEME_DEFAULT | ||
from unittest.mock import Mock, patch | ||
from pyanaconda.core.constants import PAYLOAD_TYPE_DNF, PAYLOAD_TYPE_LIVE_IMAGE | ||
|
||
|
||
class SimpleWebUITestCase(unittest.TestCase): | ||
"""Simple test case for Web UI. | ||
The goal of this test is to test execution of the UI behaves as desired. | ||
""" | ||
def setUp(self): | ||
self.intf = CockpitUserInterface(None, None, 0) | ||
|
||
def _prepare_for_live_testing(self, | ||
pid_file, | ||
pid_content="", | ||
remote=0): | ||
# prepare UI interface class | ||
self.intf = CockpitUserInterface(None, None, remote) | ||
self.intf._viewer_pid_file = pid_file.name | ||
|
||
# wrote pid if requested | ||
if pid_content: | ||
with open(pid_file.name, "wt") as f: | ||
f.write(pid_content) | ||
|
||
def test_webui_defaults(self): | ||
"""Test that webui interface has correct defaults.""" | ||
assert isinstance(self.intf.meh_interface, TextIntf) | ||
|
||
assert self.intf.tty_num == 6 | ||
|
||
# Not implemented | ||
assert self.intf.showYesNoQuestion("Implemented by browser") is False | ||
|
||
@patch("pyanaconda.ui.webui.CockpitUserInterface._print_message") | ||
def test_error_propagation(self, mocked_print_message): | ||
"""Test that webui prints erorr to the console. | ||
This gets then propagated by service to journal. | ||
""" | ||
self.intf.showError("My Error") | ||
mocked_print_message.assert_called_once_with("My Error") | ||
|
||
mocked_print_message.reset_mock() | ||
self.intf.showDetailedError("My detailed error", "Such a detail!") | ||
mocked_print_message.assert_called_once_with("My detailed error\n\nSuch a detail!""") | ||
|
||
def test_setup(self): | ||
"""Test webui setup call.""" | ||
# test not DNF payload type works fine | ||
mocked_payload = Mock() | ||
mocked_payload.type = PAYLOAD_TYPE_LIVE_IMAGE | ||
|
||
self.intf = CockpitUserInterface(None, mocked_payload, 0) | ||
self.intf.setup(None) | ||
|
||
# test DNF payload raises error because it's not yet implemented | ||
mocked_payload.type = PAYLOAD_TYPE_DNF | ||
self.intf = CockpitUserInterface(None, mocked_payload, 0) | ||
with pytest.raises(ValueError): | ||
self.intf.setup(None) | ||
|
||
@patch("pyanaconda.ui.webui.startProgram") | ||
@patch("pyanaconda.ui.webui.conf") | ||
def test_run_not_on_live(self, mocked_conf, mocked_startProgram): | ||
"""Test webui run call on boot iso.""" | ||
# Execution is different for boot.iso then live environment | ||
mocked_conf.system.provides_liveuser = False | ||
mocked_process = Mock() | ||
mocked_process.pid = 12345 | ||
mocked_startProgram.return_value = mocked_process | ||
|
||
with tempfile.NamedTemporaryFile() as ft: | ||
self._prepare_for_live_testing(ft, remote=1) | ||
self.intf.run() | ||
|
||
mocked_startProgram.assert_called_once_with(["/usr/libexec/webui-desktop", | ||
"-t", FIREFOX_THEME_DEFAULT, "-r", "1", | ||
"/cockpit/@localhost/anaconda-webui/index.html"], | ||
reset_lang=False) | ||
with open(ft.name, "rt") as f: | ||
assert f.readlines() == ["12345"] | ||
|
||
mocked_process.wait.assert_called_once() | ||
|
||
# test with disabled remote | ||
mocked_startProgram.reset_mock() | ||
mocked_process.reset_mock() | ||
mocked_startProgram.return_value = mocked_process | ||
with tempfile.NamedTemporaryFile() as ft: | ||
self._prepare_for_live_testing(ft) | ||
self.intf.run() | ||
|
||
mocked_startProgram.assert_called_once_with(["/usr/libexec/webui-desktop", | ||
"-t", FIREFOX_THEME_DEFAULT, "-r", "0", | ||
"/cockpit/@localhost/anaconda-webui/index.html"], | ||
reset_lang=False) | ||
with open(ft.name, "rt") as f: | ||
assert f.readlines() == ["12345"] | ||
|
||
mocked_process.wait.assert_called_once() | ||
|
||
@patch("pyanaconda.ui.webui.PidWatcher.watch_process") | ||
@patch("pyanaconda.ui.webui.create_main_loop") | ||
@patch("pyanaconda.ui.webui.conf") | ||
def test_run_on_live_success(self, mocked_conf, mocked_create_main_loop, mocked_watch_process): | ||
"""Test webui run call on live environment.""" | ||
# Execution is different for live because we need to start FF early as possible | ||
mocked_conf.system.provides_liveuser = True | ||
mocked_main_loop = Mock() | ||
|
||
# Test on Live media | ||
mocked_watch_process.reset_mock() | ||
mocked_create_main_loop.reset_mock() | ||
mocked_create_main_loop.return_value = mocked_main_loop | ||
mocked_main_loop.reset_mock() | ||
with tempfile.NamedTemporaryFile() as f: | ||
self._prepare_for_live_testing(f, "11111") | ||
self.intf.run() | ||
|
||
# check that callback is correctly set | ||
mocked_watch_process.assert_called_once_with(11111, self.intf._webui_desktop_closed) | ||
mocked_create_main_loop.assert_called_once() | ||
mocked_main_loop.run.assert_called_once() | ||
|
||
# test quit callbacks by calling them (simple tests avoiding execution of the main loop) | ||
# test webui callback execution - simulates closing the viewer app | ||
self.intf._webui_desktop_closed(11111, 0) | ||
mocked_main_loop.quit.assert_called_once() | ||
|
||
# test webui callback bad status - simulates crash of the viewer app | ||
mocked_main_loop.reset_mock() | ||
self.intf._webui_desktop_closed(11111, 1) | ||
mocked_main_loop.quit.assert_called_once() | ||
|
||
@patch("pyanaconda.ui.webui.PidWatcher.watch_process") | ||
@patch("pyanaconda.ui.webui.create_main_loop") | ||
@patch("pyanaconda.ui.webui.conf") | ||
def test_run_on_live_failure(self, mocked_conf, mocked_create_main_loop, mocked_watch_process): | ||
"""Test webui run call on live environment.""" | ||
mocked_conf.system.provides_liveuser = True | ||
mocked_main_loop = Mock() | ||
|
||
# Test empty pid file | ||
mocked_watch_process.reset_mock() | ||
mocked_create_main_loop.reset_mock() | ||
mocked_create_main_loop.return_value = mocked_main_loop | ||
mocked_main_loop.reset_mock() | ||
with tempfile.NamedTemporaryFile() as f: | ||
self._prepare_for_live_testing(f) | ||
with pytest.raises(ValueError): | ||
self.intf.run() | ||
|
||
mocked_watch_process.assert_not_called() | ||
mocked_create_main_loop.assert_not_called() | ||
|
||
# Test negative pid | ||
mocked_watch_process.reset_mock() | ||
mocked_create_main_loop.reset_mock() | ||
mocked_create_main_loop.return_value = mocked_main_loop | ||
mocked_main_loop.reset_mock() | ||
with tempfile.NamedTemporaryFile() as f: | ||
self._prepare_for_live_testing(f, "-20") | ||
|
||
with pytest.raises(ValueError): | ||
self.intf.run() | ||
|
||
mocked_watch_process.assert_not_called() | ||
mocked_create_main_loop.assert_not_called() | ||
|
||
# Test bad value pid | ||
mocked_watch_process.reset_mock() | ||
mocked_create_main_loop.reset_mock() | ||
mocked_create_main_loop.return_value = mocked_main_loop | ||
mocked_main_loop.reset_mock() | ||
with tempfile.NamedTemporaryFile() as f: | ||
self._prepare_for_live_testing(f, "not-a-number") | ||
|
||
with pytest.raises(ValueError): | ||
self.intf.run() | ||
|
||
mocked_watch_process.assert_not_called() | ||
mocked_create_main_loop.assert_not_called() |