[master 1/1] Multiple Dogtail tests improvements
by dashea
From: Alexander Todorov <atodorov(a)redhat.com>
- use unittest.skipIf and execute via nosetests_root.sh
- remove support for anacondaArgs because it was not used
- screenshots are placed in the correct test results directory
- logs are collected on test failures too
- cleanup mounted filesystems and update anaconda-cleanup to
use the new BlockDev loop plugin along the way
---
.gitignore | 1 +
scripts/anaconda-cleanup | 4 +--
tests/Makefile.am | 1 -
tests/gui/base.py | 29 +++++++++------
tests/nosetests_root.sh | 11 ++++++
tests/run_gui_tests.sh | 93 ------------------------------------------------
6 files changed, 33 insertions(+), 106 deletions(-)
delete mode 100755 tests/run_gui_tests.sh
diff --git a/.gitignore b/.gitignore
index 42de069..3f51d0e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -72,6 +72,7 @@ py-compile
stamp-h1
tags
test-driver
+tests/autogui-results-*/
tests/*/*/*.log
tests/*/*/*.trs
tests/*/*.log
diff --git a/scripts/anaconda-cleanup b/scripts/anaconda-cleanup
index 19e41a3..8699c7d 100755
--- a/scripts/anaconda-cleanup
+++ b/scripts/anaconda-cleanup
@@ -41,6 +41,7 @@ pyanaconda.anaconda_log.init()
from blivet.blivet import StorageDiscoveryConfig
from blivet.devicetree import DeviceTree
from blivet import devicelibs
+from gi.repository import BlockDev as blockdev
storage_config = StorageDiscoveryConfig()
@@ -56,7 +57,7 @@ for dev in os.listdir(sys_class_block):
continue
loop = os.listdir("%s/%s/slaves" % (sys_class_block, dev))[0].strip()
- storage_config.disk_images[name] = devicelibs.loop.get_backing_file(loop)
+ storage_config.disk_images[name] = blockdev.loop_get_backing_file(loop)
if not image_install:
live_install = live_install or os.path.exists("/dev/live")
@@ -87,4 +88,3 @@ for name in devicetree.disk_images.keys():
device = devicetree.get_device_by_name(name)
device.deactivate(recursive=True)
os.system("udevadm control --env=ANACONDA=0")
-
diff --git a/tests/Makefile.am b/tests/Makefile.am
index cdd8a39..e0237ea 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -53,7 +53,6 @@ dist_check_SCRIPTS = $(srcdir)/glade/*.py \
gettext_tests/canary_tests.sh \
storage/run_storage_tests.py \
install/run_install_test.sh \
- run_gui_tests.sh \
$(srcdir)/gui/*.py \
$(srcdir)/storage/cases/*.py \
$(srcdir)/*_tests/*.py
diff --git a/tests/gui/base.py b/tests/gui/base.py
index 2f76847..0674f4a 100644
--- a/tests/gui/base.py
+++ b/tests/gui/base.py
@@ -23,6 +23,7 @@
import copy
import glob
import shutil
+import selinux
import subprocess
import tempfile
import traceback
@@ -32,7 +33,7 @@
from dogtail.config import config as dogtail_config
from dogtail.predicate import GenericPredicate
from dogtail.tree import SearchError, root
-from dogtail.utils import doDelay, screenshot
+from dogtail.utils import doDelay, isA11yEnabled, screenshot
from nose.plugins.multiprocess import TimedOutException
class UITestCase(unittest.TestCase):
@@ -69,12 +70,17 @@ class UITestCase(unittest.TestCase):
which is used instead of runTest for error handling purposes.
"""
+ suite_name = None
+
def update_scratch_dir(self, name=""):
""" Update the directory where Dogtail saves screenshots. """
path = os.path.join(testconfig.config.get("resultsdir", ""), name)
if not path.endswith("/"):
path += "/"
+ if not os.path.isdir(path):
+ os.makedirs(path)
+
dogtail_config.load({"scratchDir": path})
###
@@ -86,7 +92,7 @@ def runTest(self):
anaconda should a test fail. Subclasses should not override this.
See the documentation for _run.
"""
- self.update_scratch_dir()
+ self.update_scratch_dir(self.suite_name)
try:
self._run()
@@ -240,6 +246,10 @@ def exit_spoke(self, hubName="INSTALLATION SUMMARY", node=None):
self.check_window_displayed(hubName)
+(a)unittest.skipIf(os.geteuid() != 0, "GUI tests must be run as root")
+(a)unittest.skipIf(os.environ.get("DISPLAY", "") == "", "DISPLAY must be defined")
+(a)unittest.skipIf(selinux.security_getenforce() == 1, "SELinux must be disabled or in Permissive mode, see rhbz#1276376")
+(a)unittest.skipIf(not isA11yEnabled(), "Assistive Technologies are disabled")
class DogtailTestCase(unittest.TestCase):
"""A subclass that defines all the parameters for starting a local
copy of anaconda, inspecting results, and managing temporary data!
@@ -275,7 +285,7 @@ def __init__(self, methodName='runTest'):
self.suite = unittest.TestSuite()
for test in self.tests:
T = test()
- T.update_scratch_dir(self.name)
+ T.suite_name = self.name
self.suite.addTest(T)
self.test_result = None
@@ -351,11 +361,11 @@ def die(self, terminate=False):
if terminate:
self._proc.terminate()
- # tests will click the Reboot or Quit button which will shutdown anaconda
- # we need to make sure /mnt/sysimage/* are unmounted and device mapper devices
- # are removed before starting the next test. ATM I have no idea if pyanaconda
- # provides an API for this so wait for a while instead!
- doDelay(30)
+ # Tests will click the Reboot or Quit button which will shutdown anaconda.
+ # We need to make sure /mnt/sysimage/* are unmounted and device mapper devices
+ # are removed before starting the next test.
+ subprocess.call(["%s/scripts/anaconda-cleanup" % os.environ.get("top_srcdir", "")],
+ stderr=subprocess.STDOUT)
self._proc.kill()
self._proc = None
@@ -389,7 +399,6 @@ def runTest(self):
args = ["%s/anaconda.py" % os.environ.get("top_srcdir", ""), "-G"]
for drive in self._drivePaths.values():
args += ["--image", drive]
- args += testconfig.config.get("anacondaArgs", "").strip('"')
# Save a reference to the running anaconda process so we can later kill
# it if necessary. For now, the only reason we'd want to kill it is
@@ -401,7 +410,7 @@ def runTest(self):
self.test_result = unittest.TextTestRunner(verbosity=2, failfast=True).run(self.suite)
if not self.test_result.wasSuccessful():
raise AssertionError('Dogtail tests failed')
- except TimedOutException:
+ except (TimedOutException, AssertionError):
self.die(True)
self.collect_logs()
self.cleanup()
diff --git a/tests/nosetests_root.sh b/tests/nosetests_root.sh
index 9169de8..ea65021 100755
--- a/tests/nosetests_root.sh
+++ b/tests/nosetests_root.sh
@@ -4,3 +4,14 @@
srcdir=${srcdir:=$(dirname "$0")}
exec ${srcdir}/nosetests.sh ${srcdir}/pyanaconda_tests/user_create_test.py
+
+if ! rpm -q python3-nose-testconfig &> /dev/null; then
+ echo "python3-nose-testconfig is not available; exiting."
+ exit 99
+fi
+
+export LC_ALL=C # translations confuse Dogtail
+
+exec ${srcdir}/nosetests.sh -s --nologcapture --process-timeout 1200 \
+ --tc=resultsdir:$(readlink -f autogui-results-$(date +"%Y%m%d_%H%M%S")) \
+ ${srcdir}/gui/test_*.py
diff --git a/tests/run_gui_tests.sh b/tests/run_gui_tests.sh
deleted file mode 100755
index 547ade5..0000000
--- a/tests/run_gui_tests.sh
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2014 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.
-#
-# Red Hat Author(s): Chris Lumens <clumens(a)redhat.com>
-
-# TODO: If all gui tests are properly annotated with a skipIf decorator
-# this file can be dropped and the tests executed by nosetests_root.sh
-
-function doit() {
- ARGS="-s \
- -v \
- --nologcapture \
- --process-timeout=1200 \
- --processes=1 \
- --tc=resultsdir:$(mktemp -d --tmpdir=$top_srcdir/tests autogui-results-XXXXXX)"
-
- export LC_ALL=C # translations confuse Dogtail
-
- if [ -z "$1" ]; then
- nosetests-3.5 ${ARGS} ${GUI_TESTS:-$top_srcdir/tests/gui/test_*.py}
- else
- nosetests-3.5 ${ARGS} "${1}" ${GUI_TESTS:-$top_srcdir/tests/gui/test_*.py}
- fi
-}
-
-if [ -z "$top_srcdir" ]; then
- top_srcdir="$(dirname "$0")/.."
-fi
-
-# this script needs absolute paths
-export top_srcdir=`readlink -f $top_srcdir`
-if [ ! -z "$top_builddir" ]; then
- export top_builddir=`readlink -f $top_builddir`
-fi
-. ${top_srcdir}/tests/testenv.sh
-
-if ! rpm -q python3-nose-testconfig &> /dev/null; then
- echo "test_config plugin is not available; exiting."
- exit 99
-fi
-
-# Have to be root to run this test, as it requires creating disk iamges.
-if [ ${EUID} != 0 ]; then
- echo "You must be root to run the GUI tests; skipping."
- exit 77
-fi
-
-if [ -z "${DISPLAY}" ]; then
- echo "DISPLAY is not set; skipping."
- exit 77
-fi
-
-# We need SELinux Permissive or Disabled, see rhbz#1276376
-if [ `getenforce` == "Enforcing" ]; then
- echo "SELinux is in Enforcing mode; skipping."
- exit 77
-fi
-
-# in case we want coverage support configure
-# python to start coverage for all processes
-if [ ! -z "$COVERAGE_PROCESS_START" ]; then
- ROOT_SITE_PACKAGES=`python3 -m site --user-site`
- mkdir -p "$ROOT_SITE_PACKAGES"
- if [ ! -f "$ROOT_SITE_PACKAGES/usercustomize.py" ]; then
- cp "$top_srcdir/tests/usercustomize.py" "$ROOT_SITE_PACKAGES"
- fi
-fi
-
-if [[ "${TEST_ANACONDA_ARGS}" != "" ]]; then
- EXTRA="--tc=anacondaArgs:\"${TEST_ANACONDA_ARGS}\""
-elif [[ $# != 0 ]]; then
- EXTRA="--tc=anacondaArgs:\"$*\""
-else
- EXTRA=""
-fi
-
-# execute the tests
-doit "${EXTRA}"
--
To view this commit on github, visit https://github.com/rhinstaller/anaconda/commit/8cecafb7024690a44a19891703...
8 years, 1 month
Updated: [rhinstaller/anaconda/pulls/552 rhel7-branch] Fix bad
sensitivity on boxes in source spoke (#1262833)
by dashea
~~The boxes sensitivity for source types are changed when user clicks on radio button to change type of source.
Fix problem when user enter source spoke -> nothing were clicked and everything is sensitive.~~
**EDIT:**
Remove default sensitivity on Network box. It caused more boxes were sensitive in one time.
This should work properly because the network box is setup automatically below in the code when no input method was chosen.
*Reported-by: Pavel Holica <pholica(a)redhat.com>*
*Resolves: rhbz#1262833*
I don't know why but it doesn't happened on rawhide/f24 so this is rhel7 only.
--
To view this pull request on github, visit https://github.com/rhinstaller/anaconda/pull/552
8 years, 1 month
[master 1/1] Set CSS names on all of the anaconda classes. (#1322036)
by dashea
From: David Shea <dshea(a)redhat.com>
Without this, the name usable by CSS selectors ends up being "widget".
Set the CSS name to the type name so that CSS works right again.
---
widgets/src/BaseStandalone.c | 2 ++
widgets/src/BaseWindow.c | 3 +++
widgets/src/DiskOverview.c | 3 +++
widgets/src/HubWindow.c | 3 +++
widgets/src/LayoutIndicator.c | 3 +++
widgets/src/MountpointSelector.c | 3 +++
widgets/src/SpokeSelector.c | 3 +++
widgets/src/SpokeWindow.c | 3 +++
widgets/src/StandaloneWindow.c | 3 +++
9 files changed, 26 insertions(+)
diff --git a/widgets/src/BaseStandalone.c b/widgets/src/BaseStandalone.c
index 70813fe..8875365 100644
--- a/widgets/src/BaseStandalone.c
+++ b/widgets/src/BaseStandalone.c
@@ -152,6 +152,8 @@ static void anaconda_base_standalone_class_init(AnacondaBaseStandaloneClass *kla
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
g_type_class_add_private(object_class, sizeof(AnacondaBaseStandalonePrivate));
+
+ gtk_widget_class_set_css_name(widget_class, "AnacondaBaseStandalone");
}
static void anaconda_base_standalone_init(AnacondaBaseStandalone *win) {
diff --git a/widgets/src/BaseWindow.c b/widgets/src/BaseWindow.c
index 87db73d..533df09 100644
--- a/widgets/src/BaseWindow.c
+++ b/widgets/src/BaseWindow.c
@@ -181,6 +181,7 @@ G_DEFINE_TYPE_WITH_CODE(AnacondaBaseWindow, anaconda_base_window, GTK_TYPE_BIN,
static void anaconda_base_window_class_init(AnacondaBaseWindowClass *klass) {
GObjectClass *object_class = G_OBJECT_CLASS(klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
object_class->set_property = anaconda_base_window_set_property;
object_class->get_property = anaconda_base_window_get_property;
@@ -264,6 +265,8 @@ static void anaconda_base_window_class_init(AnacondaBaseWindowClass *klass) {
G_TYPE_NONE, 0);
g_type_class_add_private(object_class, sizeof(AnacondaBaseWindowPrivate));
+
+ gtk_widget_class_set_css_name(widget_class, "AnacondaBaseWindow");
}
/**
diff --git a/widgets/src/DiskOverview.c b/widgets/src/DiskOverview.c
index da2f0ba..2d7dfe8 100644
--- a/widgets/src/DiskOverview.c
+++ b/widgets/src/DiskOverview.c
@@ -133,6 +133,7 @@ static gboolean anaconda_disk_overview_focus_changed(GtkWidget *widget, GdkEvent
static void anaconda_disk_overview_class_init(AnacondaDiskOverviewClass *klass) {
GObjectClass *object_class = G_OBJECT_CLASS(klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
object_class->set_property = anaconda_disk_overview_set_property;
object_class->get_property = anaconda_disk_overview_get_property;
@@ -238,6 +239,8 @@ static void anaconda_disk_overview_class_init(AnacondaDiskOverviewClass *klass)
G_PARAM_READWRITE));
g_type_class_add_private(object_class, sizeof(AnacondaDiskOverviewPrivate));
+
+ gtk_widget_class_set_css_name(widget_class, "AnacondaDiskOverview");
}
/**
diff --git a/widgets/src/HubWindow.c b/widgets/src/HubWindow.c
index bacbb0e..ebec30b 100644
--- a/widgets/src/HubWindow.c
+++ b/widgets/src/HubWindow.c
@@ -100,8 +100,11 @@ G_DEFINE_TYPE_WITH_CODE(AnacondaHubWindow, anaconda_hub_window, ANACONDA_TYPE_BA
static void anaconda_hub_window_class_init(AnacondaHubWindowClass *klass) {
GObjectClass *object_class = G_OBJECT_CLASS(klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
g_type_class_add_private(object_class, sizeof(AnacondaHubWindowPrivate));
+
+ gtk_widget_class_set_css_name(widget_class, "AnacondaHubWindow");
}
/**
diff --git a/widgets/src/LayoutIndicator.c b/widgets/src/LayoutIndicator.c
index ebfbad6..aefb1b3 100644
--- a/widgets/src/LayoutIndicator.c
+++ b/widgets/src/LayoutIndicator.c
@@ -108,6 +108,7 @@ static GdkFilterReturn handle_xevent(GdkXEvent *xev, GdkEvent *event, gpointer e
static void anaconda_layout_indicator_class_init(AnacondaLayoutIndicatorClass *klass) {
GObjectClass *object_class = G_OBJECT_CLASS(klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
object_class->get_property = anaconda_layout_indicator_get_property;
object_class->set_property = anaconda_layout_indicator_set_property;
@@ -144,6 +145,8 @@ static void anaconda_layout_indicator_class_init(AnacondaLayoutIndicatorClass *k
G_PARAM_READWRITE));
g_type_class_add_private(object_class, sizeof(AnacondaLayoutIndicatorPrivate));
+
+ gtk_widget_class_set_css_name(widget_class, "AnacondaLayoutIndicator");
}
/**
diff --git a/widgets/src/MountpointSelector.c b/widgets/src/MountpointSelector.c
index 13b96c1..549f92c 100644
--- a/widgets/src/MountpointSelector.c
+++ b/widgets/src/MountpointSelector.c
@@ -113,6 +113,7 @@ static void anaconda_mountpoint_selector_toggle_background(AnacondaMountpointSel
static void anaconda_mountpoint_selector_class_init(AnacondaMountpointSelectorClass *klass) {
GObjectClass *object_class = G_OBJECT_CLASS(klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
object_class->set_property = anaconda_mountpoint_selector_set_property;
object_class->get_property = anaconda_mountpoint_selector_get_property;
@@ -202,6 +203,8 @@ static void anaconda_mountpoint_selector_class_init(AnacondaMountpointSelectorCl
NULL); // array of types, one for each parameter
g_type_class_add_private(object_class, sizeof(AnacondaMountpointSelectorPrivate));
+
+ gtk_widget_class_set_css_name(widget_class, "AnacondaMountpointSelector");
}
/**
diff --git a/widgets/src/SpokeSelector.c b/widgets/src/SpokeSelector.c
index eac30e0..96232ea 100644
--- a/widgets/src/SpokeSelector.c
+++ b/widgets/src/SpokeSelector.c
@@ -104,6 +104,7 @@ static gboolean anaconda_spoke_selector_focus_changed(GtkWidget *widget, GdkEven
static void anaconda_spoke_selector_class_init(AnacondaSpokeSelectorClass *klass) {
GObjectClass *object_class = G_OBJECT_CLASS(klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
object_class->set_property = anaconda_spoke_selector_set_property;
object_class->get_property = anaconda_spoke_selector_get_property;
@@ -166,6 +167,8 @@ static void anaconda_spoke_selector_class_init(AnacondaSpokeSelectorClass *klass
G_PARAM_READWRITE));
g_type_class_add_private(object_class, sizeof(AnacondaSpokeSelectorPrivate));
+
+ gtk_widget_class_set_css_name(widget_class, "AnacondaSpokeSelector");
}
/**
diff --git a/widgets/src/SpokeWindow.c b/widgets/src/SpokeWindow.c
index d86587a..ef227d1 100644
--- a/widgets/src/SpokeWindow.c
+++ b/widgets/src/SpokeWindow.c
@@ -74,6 +74,7 @@ static void anaconda_spoke_window_button_clicked(GtkButton *button,
static void anaconda_spoke_window_class_init(AnacondaSpokeWindowClass *klass) {
GObjectClass *object_class = G_OBJECT_CLASS(klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
klass->button_clicked = NULL;
@@ -99,6 +100,8 @@ static void anaconda_spoke_window_class_init(AnacondaSpokeWindowClass *klass) {
G_TYPE_NONE, 0);
g_type_class_add_private(object_class, sizeof(AnacondaSpokeWindowPrivate));
+
+ gtk_widget_class_set_css_name(widget_class, "AnacondaSpokeWindow");
}
/**
diff --git a/widgets/src/StandaloneWindow.c b/widgets/src/StandaloneWindow.c
index 30e73e5..28a8cbf 100644
--- a/widgets/src/StandaloneWindow.c
+++ b/widgets/src/StandaloneWindow.c
@@ -70,6 +70,7 @@ G_DEFINE_TYPE(AnacondaStandaloneWindow, anaconda_standalone_window, ANACONDA_TYP
static void anaconda_standalone_window_class_init(AnacondaStandaloneWindowClass *klass) {
GObjectClass *object_class = G_OBJECT_CLASS(klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
object_class->get_property = anaconda_standalone_window_get_property;
@@ -113,6 +114,8 @@ static void anaconda_standalone_window_class_init(AnacondaStandaloneWindowClass
G_PARAM_READABLE));
g_type_class_add_private(object_class, sizeof(AnacondaStandaloneWindowPrivate));
+
+ gtk_widget_class_set_css_name(widget_class, "AnacondaStandaloneWindow");
}
static void anaconda_standalone_window_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
--
To view this commit on github, visit https://github.com/rhinstaller/anaconda/commit/3a4e407acafe0e2a12758eeab8...
8 years, 1 month