Skip to content

Commit

Permalink
Add test for scientific python packages
Browse files Browse the repository at this point in the history
This commit adds a test for numpy and scipy packages on openSUSE and
SLE>=15
  • Loading branch information
felix.niederwanger@suse.com committed Jan 6, 2021
1 parent 0eaabca commit ec3676a
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 3 deletions.
60 changes: 60 additions & 0 deletions data/python/python3-numpy-test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Test for basic numpy routines
# Maintainer: Felix Niederwanger <felix.niederwanger@suse.de>


import numpy as np
import math


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
63 changes: 63 additions & 0 deletions tests/console/python_scientific.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# 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);

sub run_python_script {
my $script = shift;
my $logfile = "output.txt";
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 {
cleanup();
}

sub post_run_hook {
cleanup();
}

1;

0 comments on commit ec3676a

Please sign in to comment.