diff --git a/data/python/bs4/python3-beautifulsoup4-test.py b/data/python/bs4/python3-beautifulsoup4-test.py new file mode 100644 index 000000000000..3b85b5480c7e --- /dev/null +++ b/data/python/bs4/python3-beautifulsoup4-test.py @@ -0,0 +1,6 @@ +import bs4 as bs +with open ("testpage.html") as file: + source = file.read() + +soup=bs.BeautifulSoup(source,'lxml') +assert soup.title.string=='Python Programming Tutorials' \ No newline at end of file diff --git a/data/python/bs4/testpage.html b/data/python/bs4/testpage.html new file mode 100644 index 000000000000..d0020856074a --- /dev/null +++ b/data/python/bs4/testpage.html @@ -0,0 +1,301 @@ + + + + + + Python Programming Tutorials + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ +

Oh, hello! This is a wonderful page meant to let + you practice web scraping. This page was originally created to help people work with the Beautiful Soup + 4 library.

+ +

The following table gives some general information for the following programming languages: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Program NameInternet PointsKittens?
Python932914021Definitely
Pascal532Unlikely
Lisp1522Uncertain
D#12Possibly
Cobol3No.
Fortran52124Yes.
Haskell24lol.
+ +

I think it's clear that, on a scale of 1-10, python is:

+ +
+
+
+ omg batman +
+
+ +

Javascript (dynamic data) test:

+

y u bad tho?

+ + +

+ +
Beautiful is better than ugly.
+Explicit is better than implicit.
+Simple is better than complex.
+Complex is better than complicated.
+Flat is better than nested.
+Sparse is better than dense.
+Readability counts.
+Special cases aren't special enough to break the rules.
+Although practicality beats purity.
+Errors should never pass silently.
+Unless explicitly silenced.
+In the face of ambiguity, refuse the temptation to guess.
+There should be one-- and preferably only one --obvious way to do it.
+Although that way may not be obvious at first unless you're Dutch.
+Now is better than never.
+Although never is often better than *right* now.
+If the implementation is hard to explain, it's a bad idea.
+If the implementation is easy to explain, it may be a good idea.
+Namespaces are one honking great idea -- let's do more of those!
+ +

Whᶐt hαppéns now¿

+ +

sitemap

+ + + + +
+
+ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/python_version_utils.pm b/lib/python_version_utils.pm new file mode 100644 index 000000000000..65261e3c6c4c --- /dev/null +++ b/lib/python_version_utils.pm @@ -0,0 +1,79 @@ +# Copyright 2015-2022 SUSE LLC +# SPDX-License-Identifier: GPL-2.0-or-later + +package python_version_utils; + +use base Exporter; +use Exporter; +use testapi; +use utils 'zypper_call'; +use strict; +use warnings; +use v5.20; +use feature qw(signatures); +no warnings qw(experimental::signatures); + + +our @EXPORT = qw( + get_system_python_version + get_available_python_versions + get_python3_binary + remove_installed_pythons +); + +=head2 get_system_python_version + +returns a string with the system's current default python version, for example 'python311' +=cut + +sub get_system_python_version() { + my @system_python_version = script_output(qq[zypper se --installed-only --provides '/usr/bin/python3' | awk -F '|' '/python3[0-9]*/ {gsub(" ", ""); print \$2}' | awk -F '-' '{print \$1}' | uniq]); + die "There are many python3 versions installed " if (scalar(@system_python_version) > 1); + return $system_python_version[0]; +} + +=head2 get_available_python_versions + +returns an array of strings with all the available python versions in the repository +=cut + +sub get_available_python_versions() { + my @python3_versions = split(/\n/, script_output(qq[zypper se 'python3[0-9]*' | awk -F '|' '/python3[0-9]/ {gsub(" ", ""); print \$2}' | awk -F '-' '{print \$1}' | uniq])); + record_info("Available versions", "All available new python3 versions are: @python3_versions"); + return @python3_versions; +} + +=head2 get_python3_binary + +given a python package version, e.g. python311, returns the executable name python3.11 +when the package is 'python3', return the system default one (eg python3.6 for SLE15.4) +=cut + +sub get_python3_binary ($python3_package) { + if ($python3_package eq "python3") { + my $current_version = script_output("rpm -q python3 --queryformat '%{version}'"); + $current_version =~ s/\.\d+$//; + return "python$current_version"; + } + my $sub_version = substr($python3_package, 7); + return "python3.$sub_version"; +} + +=head2 remove_installed_pythons + +remove all the installed available python versions +=cut + +sub remove_installed_pythons() { + my $default_python = script_output("python3 --version | awk -F ' ' '{print \$2}\'"); + my @python3_versions = split(/\n/, script_output(qq[zypper se -i 'python3[0-9]*' | awk -F '|' '/python3[0-9]/ {gsub(" ", ""); print \$2}' | awk -F '-' '{print \$1}' | uniq])); + record_info("Installed versions", "All Installed new python3 versions are: @python3_versions"); + foreach my $python3_spec_release (@python3_versions) { + my $python_versions = script_output("rpm -q $python3_spec_release | awk -F \'-\' \'{print \$2}\'"); + record_info("Python version", "$python_versions:$default_python"); + next if ($python_versions eq $default_python); + zypper_call("remove $python3_spec_release-base"); + } +} + +1; diff --git a/schedule/qam/common/mau-extratests1.yaml b/schedule/qam/common/mau-extratests1.yaml index f1552f37b69f..e03994313238 100644 --- a/schedule/qam/common/mau-extratests1.yaml +++ b/schedule/qam/common/mau-extratests1.yaml @@ -45,12 +45,14 @@ conditional_schedule: - console/redis - console/python3_new_version_check - console/python3_setuptools + - console/python3_beautifulsoup4 - '{{arch_specific}}' 15-SP4: - console/golang - console/redis - console/python3_new_version_check - console/python3_setuptools + - console/python3_beautifulsoup4 - '{{arch_specific}}' 15-SP3: - console/openssl_nodejs diff --git a/tests/console/python3_beautifulsoup4.pm b/tests/console/python3_beautifulsoup4.pm new file mode 100644 index 000000000000..d043391ca963 --- /dev/null +++ b/tests/console/python3_beautifulsoup4.pm @@ -0,0 +1,63 @@ +# SUSE's openQA tests +# +# Copyright SUSE LLC +# SPDX-License-Identifier: FSFAP +# +# Summary: python3-beautifulsoup tests +# - install python-beautifulsoup package +# - use library to parse sample htmlfile +# - Compare the result vs expected +# +# Maintainer: QE-Core + +use base 'consoletest'; +use warnings; +use strict; +use v5.20; +use feature qw(signatures); +no warnings qw(experimental::signatures); +use testapi; +use serial_terminal 'select_serial_terminal'; +use utils 'zypper_call'; +use python_version_utils; + + +sub test_setup { + select_serial_terminal; + # Import python script and sample html file + assert_script_run("curl -O " . data_url("python/bs4/python3-beautifulsoup4-test.py")); + assert_script_run("curl -O " . data_url("python/bs4/testpage.html")); +} + +sub run_test ($python_package) { + record_info("Testing for $python_package"); + zypper_call("install $python_package $python_package-beautifulsoup4 $python_package-lxml"); + my $python_interpreter = get_python3_binary($python_package); + record_info("running python version", script_output("$python_interpreter --version")); + # Execute python script. The script itself ensure output is the one expected + assert_script_run("$python_interpreter python3-beautifulsoup4-test.py"); + # clean up for the next run + zypper_call("rm $python_package $python_package-beautifulsoup4 $python_package-lxml") +} + +sub run { + my $self = shift; + test_setup; + my @python3_versions = get_available_python_versions(); + unshift @python3_versions, "python3"; # append the system default one + run_test($_) foreach @python3_versions; + cleanup(); +} + +sub post_fail_hook { + my $self = shift; + cleanup(); + $self->SUPER::post_fail_hook; +} + +sub cleanup { + remove_installed_pythons(); + script_run("rm -f python3-beautifulsoup4-test.py testpage.html"); +} + +1;