Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test for scientific python packages #11699

Merged
merged 1 commit into from
Jan 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
61 changes: 61 additions & 0 deletions data/python/python3-numpy-test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Test for basic numpy routines
# Maintainer: Felix Niederwanger <felix.niederwanger@suse.de>


import math

import numpy as np


def _rotMatrix(theta):
# Build rotation matrix
R = np.zeros((2, 2))
cosTheta, sinTheta = math.cos(theta), math.sin(theta)
R[0, 1] = cosTheta
R[0, 1] = -sinTheta
R[1, 0] = sinTheta
R[1, 1] = cosTheta
return R


# rotate vector v by angle theta (in radians)
def rotate(v, theta):
return np.matmul(v, _rotMatrix(theta))


def v_eq(v1, v2, tol=1e-6):
# Check if two vectors are within a given numerical tolerance
d = v1 - v2
val = np.dot(d, d) # dot product is the square of the distance
return val < (tol * tol)


if __name__ == "__main__":
# Create two test vectors
v1, v2 = np.array([2, 1]), np.array([-2, 1])
v1 = np.transpose(v1)
v2 = np.transpose(v2)
# Rotate test vectors
theta = math.pi / 2.0 # 90 degrees
r1, r2 = rotate(v1, theta), rotate(v2, theta)
if not v_eq(r1, np.array([1, -2])):
raise ValueError("v1 rotation failed")
if not v_eq(r2, np.array([1, 2])):
raise ValueError("v2 rotation failed")

## Test some stochastic operations

# Create sinus function
x = np.arange(0, 4 * np.pi, 0.01)
y = np.sin(x)

avg, std = np.average(y), np.std(y)
if abs(avg) > 1e-5:
raise ValueError("Average above numerical tolerance")
# Note: Expected standart deviation for sample: 0.7070046915466268
if abs(std - 0.707) > 1e-3:
raise ValueError("Std above numerical tolerance")

print("OK")
62 changes: 62 additions & 0 deletions data/python/python3-scipy-test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Test for some basic scipy routines
# * do 1 simple 1d discrete fourier transformation
# Maintainer: Felix Niederwanger <felix.niederwanger@suse.de>


import math

import numpy as np
from scipy.integrate import quad, simps


def max_difference(a1, a2):
return np.absolute(a1 - a2).max()


if __name__ == "__main__":
try:
from scipy.fft import fft, ifft

print("scipy-fft module present")
## Create input functions
x = np.arange(-4 * np.pi, 4 * np.pi, 0.1)
y1 = np.sin(x)
y2 = np.sin(2 * x)
y = y1 + y2

print("Performing fft ... ")
# Note: Fourier(f+g) = Fourier(f) + Fourier(g)
fr_y1 = fft(y)
fr_y2 = fft(y1) + fft(y2)

## Check if both resulting functions are the same
max_diff = max_difference(fr_y1, fr_y2)
print(" Max difference: %.2e" % (max_diff))
if max_diff > 1e-5:
raise ValueError("fft function check failed")

## Inverse fft is the actual cross-check:
## check if: ifft( fft(y1) + fft(y2)) = y1+y2
print("Inverse fft ... ")
y_inv = ifft(fr_y2)
max_diff = max_difference(y, y_inv)
print(" Max difference: %.2e" % (max_diff))
if max_diff > 1e-5:
raise ValueError("inverse fft function check failed")
except ImportError:
print("Softfail: bsc#1180605 - scipy-fft module not found")

## Test integration
print("Test integrators ... ")
x = np.array([1, 2, 3, 4])
integral = simps(x ** 2, x) # Integrate x^2 from 1..4. Exact result: 21
if abs(integral - 21.0) > 0.5:
raise ValueError("Simpson integration failed")
integral = quad(lambda x: x ** 3, 1, 4)[
0
] # Integrate x^3 from 1..4. Exact result: 63.75
if abs(integral - 63.75) > 0.5:
raise ValueError("quad integration failed")
print("OK")
7 changes: 4 additions & 3 deletions lib/main_common.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1692,9 +1692,10 @@ sub load_extra_tests_console {
loadtest 'console/osinfo_db' if (is_sle('12-SP3+') && !is_jeos);
loadtest 'console/libgcrypt' if ((is_sle(">=12-SP4") && (check_var_array('ADDONS', 'sdk') || check_var_array('SCC_ADDONS', 'sdk'))) || is_opensuse);
loadtest "console/gd";
loadtest 'console/valgrind' unless is_sle('<=12-SP3');
loadtest 'console/sssd_samba' unless (is_sle("<15") || is_sle(">=15-sp2") || is_leap('>=15.2') || is_tumbleweed);
loadtest 'console/wpa_supplicant' unless (!is_x86_64 || is_sle('<15') || is_leap('<15.1') || is_jeos || is_public_cloud);
loadtest 'console/valgrind' unless is_sle('<=12-SP3');
loadtest 'console/sssd_samba' unless (is_sle("<15") || is_sle(">=15-sp2") || is_leap('>=15.2') || is_tumbleweed);
loadtest 'console/wpa_supplicant' unless (!is_x86_64 || is_sle('<15') || is_leap('<15.1') || is_jeos || is_public_cloud);
loadtest 'console/python-scientific' unless (is_sle("<15"));
loadtest "console/parsec" if is_tumbleweed;
}

Expand Down
1 change: 1 addition & 0 deletions schedule/qam/15-SP1/mau-extratests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ schedule:
- console/gd
- console/valgrind
- console/sssd_samba
- console/python_scientific
- '{{wpa_supplicant}}'
- console/coredump_collect
conditional_schedule:
Expand Down
1 change: 1 addition & 0 deletions schedule/qam/15-SP2/mau-extratests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ schedule:
- console/libqca2
- console/gd
- console/valgrind
- console/python_scientific
- '{{wpa_supplicant}}'
- console/coredump_collect
conditional_schedule:
Expand Down
1 change: 1 addition & 0 deletions schedule/qam/15/mau-extratests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ schedule:
- console/gd
- console/valgrind
- console/sssd_samba
- console/python_scientific
- '{{wpa_supplicant}}'
- console/coredump_collect
conditional_schedule:
Expand Down
68 changes: 68 additions & 0 deletions tests/console/python_scientific.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# SUSE's openQA tests
#
# Copyright © 2021 SUSE LLC
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved. This file is offered as-is,
# without any warranty.

# Summary: Scientific python packages
# * Test numpy
# * Test scipy
# Maintainer: Felix Niederwanger <felix.niederwanger@suse.de>

use base 'consoletest';
use strict;
use warnings;
use testapi;
use utils;
use version_utils qw(is_sle);
use registration qw(cleanup_registration register_product add_suseconnect_product get_addon_fullname remove_suseconnect_product);
dzedro marked this conversation as resolved.
Show resolved Hide resolved

sub run_python_script {
my $script = shift;
my $logfile = "output.txt";
grisu48 marked this conversation as resolved.
Show resolved Hide resolved
record_info($script, "Running python script: $script");
assert_script_run("curl " . data_url("python/$script") . " -o '$script'");
assert_script_run("chmod a+rx '$script'");
assert_script_run("./$script 2>&1 | tee $logfile");
if (script_run("grep 'Softfail' $logfile") == 0) {
my $failmsg = script_output("grep 'Softfail' '$logfile'");
record_soft_failure("$failmsg");
}
}

sub run {
my $self = shift;
$self->select_serial_terminal;
if (is_sle) {
cleanup_registration();
register_product();
add_suseconnect_product(get_addon_fullname('phub'));
}
zypper_call 'in python3 python3-numpy python3-scipy';
# Run python scripts
run_python_script('python3-numpy-test.py');
run_python_script('python3-scipy-test.py');
}

sub cleanup() {
if (is_sle) {
remove_suseconnect_product(get_addon_fullname('phub'));
}
}

sub post_fail_hook {
my $self = shift;
cleanup();
grisu48 marked this conversation as resolved.
Show resolved Hide resolved
$self->SUPER::post_fail_hook;
}

sub post_run_hook {
my $self = shift;
cleanup();
grisu48 marked this conversation as resolved.
Show resolved Hide resolved
$self->SUPER::post_run_hook;
}

1;