From 8211a23745686d564d2bc5c7b9c85da04512c05a Mon Sep 17 00:00:00 2001
From: Gennady Pospelov <g.pospelov@fz-juelich.de>
Date: Tue, 4 Apr 2017 16:17:05 +0200
Subject: [PATCH] New PyExamples functional test machinery for embedded script
 testing

---
 Tests/Functional/CMakeLists.txt               |  1 +
 Tests/Functional/PyExamples/CMakeLists.txt    | 28 +++++++
 .../PyExamples/check_functionality.py         | 78 +++++++++++++++++++
 3 files changed, 107 insertions(+)
 create mode 100644 Tests/Functional/PyExamples/CMakeLists.txt
 create mode 100644 Tests/Functional/PyExamples/check_functionality.py

diff --git a/Tests/Functional/CMakeLists.txt b/Tests/Functional/CMakeLists.txt
index 6ca76d783b7..ec9698a6755 100644
--- a/Tests/Functional/CMakeLists.txt
+++ b/Tests/Functional/CMakeLists.txt
@@ -20,6 +20,7 @@ if(BORNAGAIN_PYTHON)
     add_subdirectory(PyCore/export)
     add_subdirectory(PyCore/persistence)
     add_subdirectory(PyFit)
+    add_subdirectory(PyExamples)
 endif()
 
 if(BORNAGAIN_GUI)
diff --git a/Tests/Functional/PyExamples/CMakeLists.txt b/Tests/Functional/PyExamples/CMakeLists.txt
new file mode 100644
index 00000000000..faea206e7dc
--- /dev/null
+++ b/Tests/Functional/PyExamples/CMakeLists.txt
@@ -0,0 +1,28 @@
+###############################################################################
+# Tests/Functional/PyExamples/CMakeLists.txt
+#
+# > Test functionality of all examples found in PY_EXAMPLES_DIR = <BornAgain>/Examples/python
+# > Validates selected examples against reference files
+#
+###############################################################################
+
+add_custom_target(TempQtCreatorTarget SOURCES check_functionality.py)
+
+set(examples
+    simulation/ex01_BasicParticles/CylindersAndPrisms
+    )
+
+
+set(test_script ${CMAKE_SOURCE_DIR}/Tests/Functional/PyExamples/check_functionality.py)
+
+foreach(example ${examples})
+    set(script_path ${PY_EXAMPLES_DIR}/${example}.py)
+
+    get_filename_component(script_name ${script_path} NAME_WE)
+    set(test_name PyExamples/${script_name})
+
+    add_test(${test_name} ${PYTHON_EXECUTABLE} ${test_script} ${script_path})
+    set_tests_properties(${test_name} PROPERTIES LABELS "Examples")
+
+    message(INFO "XXX ${PYTHON_EXECUTABLE} ${test_script} ${script_path}")
+endforeach()
diff --git a/Tests/Functional/PyExamples/check_functionality.py b/Tests/Functional/PyExamples/check_functionality.py
new file mode 100644
index 00000000000..2ab620e5c36
--- /dev/null
+++ b/Tests/Functional/PyExamples/check_functionality.py
@@ -0,0 +1,78 @@
+"""
+Checks functionality of BornAgain Python example by running it in 'embedded' way.
+Usage: python check_functionality.py <path-to-example>/example.py
+
+Example is considered as functional, if it runs without exceptions thrown and
+generates non-zero-size intensity image.
+
+"""
+
+import sys
+import os
+import matplotlib
+matplotlib.use('Agg')
+from matplotlib import pyplot as plt
+
+
+def get_figure(filename):
+    """
+    Returns pyplot figure of appropriate size
+    """
+    if "AllFormFactorsAvailable" in filename:
+        xsize, ysize = 1024, 768
+    else:
+        xsize, ysize = 640, 480
+
+    dpi = 72.
+    return plt.figure(figsize=(xsize/dpi, ysize/dpi))
+
+
+def exec_full(filepath):
+    """
+    Executes embedded python script.
+    http://stackoverflow.com/questions/436198/what-is-an-alternative-to-execfile-in-python-3
+    """
+    import os
+    global_namespace = {
+        "__file__": filepath,
+        "__name__": "__main__",
+    }
+    sys.argv = []  # FIXME after cleanup in plot_utils
+    with open(filepath, 'rb') as file:
+        exec(compile(file.read(), filepath, 'exec'), global_namespace)
+
+
+def run_example(filename):
+    """
+    Tries to run python example and produce a *.png image
+    """
+    print(filename)
+
+    fig = get_figure(filename)
+    try:
+        exec_full(filename)
+
+        plot_file_name = os.path.splitext(os.path.basename(filename))[0] + ".png"
+        print(plot_file_name)
+        plt.savefig(plot_file_name, bbox_inches='tight')
+        plt.close(fig)
+
+        status = "OK"
+
+        kb = os.path.getsize(plot_file_name)/1000.
+        if kb < 4.0:
+            status = "EMPTY?"
+
+    except:
+        status = "FAILED"
+
+    print(status)
+    # return os.path.join(dirname, filename), status, ""
+
+
+if __name__ == '__main__':
+
+    if len(sys.argv) != 2:
+        exit("Error")
+
+    run_example(sys.argv[1])
-- 
GitLab