From d887f3f75c22922cbc16cb74e167d3d34eb752aa Mon Sep 17 00:00:00 2001
From: ahmedk <karim.ahmed@xfel.eu>
Date: Mon, 4 Apr 2022 17:51:16 +0200
Subject: [PATCH] Avoid creation-time for the time being and update docstring

---
 tests/test_pre_deployment.py | 101 ++++++++++++++++++++++++++---------
 1 file changed, 76 insertions(+), 25 deletions(-)

diff --git a/tests/test_pre_deployment.py b/tests/test_pre_deployment.py
index 550370ff3..99465fae7 100644
--- a/tests/test_pre_deployment.py
+++ b/tests/test_pre_deployment.py
@@ -8,7 +8,7 @@ from contextlib import redirect_stdout
 from datetime import datetime
 from functools import partial
 from subprocess import PIPE, run
-from typing import Any, Dict, List
+from typing import Any, Dict, List, Tuple
 
 import h5py
 import pytest
@@ -17,15 +17,25 @@ import yaml
 import xfel_calibrate.calibrate as calibrate
 from cal_tools import h5_copy_except
 
-REFERENCE_FOLDER = "/gpfs/exfel/data/scratch/ahmedk/test/deployed_3.5.0a1/"
-OUT_FOLDER = "/gpfs/exfel/data/scratch/ahmedk/test/remove/"
+REFERENCE_FOLDER = "/gpfs/exfel/data/scratch/ahmedk/test/release_test_3.5.0b3/"
+OUT_FOLDER = "/gpfs/exfel/data/scratch/ahmedk/test/3.5.1test1/"
 
 with open("./tests/callab_tests.yaml", "r") as f:
     callab_test_dict = yaml.load(f)
 
 
-def file_md5(filename, block_size=2**20):
-    f = open(filename, "rb")
+def file_md5(
+    tested_file: str,
+    block_size: int = 2**20,
+) -> bytes:
+    """Generating MD5 checksum for a file.
+
+    Args:
+        tested_file: File to be tested.
+        block_size (_type_, optional): Block size for reading the file.
+            Defaults to 2**20.
+    """
+    f = open(tested_file, "rb")
     md5 = hashlib.md5()
     while True:
         data = f.read(block_size)
@@ -36,11 +46,43 @@ def file_md5(filename, block_size=2**20):
     return md5.digest()
 
 
-def validate_h5files(f, ref_folder):
+def validate_h5files(
+    f: pathlib.PosixPath,
+    ref_folder: pathlib.PosixPath
+) -> Tuple[bool, pathlib.PosixPath]:
+    """Validate the h5files based on the generated MD5 checksum.
+
+    Args:
+        f: file to validate
+        ref_folder (_type_): Reference folder which has the same filename
+            as of the file to validate.
+
+    Returns:
+        Validation result.
+        The validate file.
+    """
     return file_md5(f) == file_md5(ref_folder / f.name), f
 
 
-def validate_constant_files(ref_folder, out_folder, out_f):
+def validate_constant_file(
+    ref_folder: pathlib.PosixPath,
+    out_folder: pathlib.PosixPath,
+    test_file: pathlib.PosixPath
+) -> Tuple[bool, bool, pathlib.PosixPath]:
+    """Validate the constants files by validating the metadata
+    stored in the h5files, e.g. conditions and db_modules. This is
+    done after excluding the report and data.
+
+    Args:
+        ref_folder: The reference folder for validating the files
+        out_folder: The output folder for the test constant files.
+        out_f: The output file to be validated.
+
+    Returns:
+        result: validation result for metadata.
+        test_file: The validated file.
+
+    """
     out_tf = tempfile.NamedTemporaryFile(
         dir=out_folder,
         suffix=".tmp",
@@ -56,20 +98,21 @@ def validate_constant_files(ref_folder, out_folder, out_f):
     hp1 = h5py.File(out_tf.name, 'w', driver='core', backing_store=True)
     hp2 = h5py.File(ref_tf.name, 'w', driver='core', backing_store=True)
     # Copy RAW non-calibrated sources.
-    with h5py.File(out_f, 'r') as sfile:
+    with h5py.File(test_file, 'r') as sfile:
         h5_copy_except.h5_copy_except_paths(
-            sfile, hp1, ["report"],
+            sfile, hp1, ["report", "creation_time"],
         )
-    with h5py.File(ref_folder / out_f.name, 'r') as sfile:
+    with h5py.File(ref_folder / test_file.name, 'r') as sfile:
         h5_copy_except.h5_copy_except_paths(
-            sfile, hp2, ["report"],
+            sfile, hp2, ["report", "creation_time"],
         )
     hp1.close()
     hp2.close()
-    result = file_md5(out_tf.name) == file_md5(ref_tf.name), out_f
+    result = file_md5(out_tf.name) == file_md5(ref_tf.name)
     out_tf.close()
     ref_tf.close()
-    return result
+
+    return result, test_file
 
 
 def parse_config(
@@ -107,18 +150,28 @@ def parse_config(
 
 @pytest.mark.manual_run
 @pytest.mark.parametrize(
-    "k, v",
+    "test_key, val_dict",
     list(callab_test_dict.items()),
     ids=list(callab_test_dict.keys()),
 )
-def test_xfel_calibrate(k, v, release_test_config):
+def test_xfel_calibrate(
+    test_key: str, val_dict: dict,
+    release_test_config: Tuple[bool, bool, bool, bool]
+):
+    """ Test xfel calibrate detectors and calibrations written
+    in the given callab_test YAML file.
+    Args:
+        test_key : Key for the xfel-calibrate test.
+        val_dict: Dictionary of the configurations for the running test.
+        release_test_config: Tuple of booleans to pick or skip tests
+            based on the given boolean configs.
+    """
 
     (
         detectors, calibration,
         picked_test, skip_numerical_validation
     ) = release_test_config
 
-    test_key, val_dict = k, v
     cal_type = val_dict["cal_type"]
     det_type = val_dict["det_type"]
 
@@ -181,6 +234,7 @@ def test_xfel_calibrate(k, v, release_test_config):
     states = res.stdout.decode().split("\n")[2:-1]
     assert all(s.strip() == "COMPLETED" for s in states), f"{test_key} failure, calibration jobs were not completed. {jobids}: {states}"  # noqa
     print(f"{test_key}'s jobs were COMPLETED")
+    time.sleep(1.0)
 
     # 2nd check for report availability.
     report_file = out_folder / f"{report_name}.pdf"
@@ -195,23 +249,20 @@ def test_xfel_calibrate(k, v, release_test_config):
     # Stop tests at this point, if desired.
     if skip_numerical_validation:
         return
-
-    # 4th check that h5files are exactly the same as the reference h5files.
-    all_files_validated = []
     non_valid_files = []
 
+    # 4th check that h5files are exactly the same as the reference h5files.
     if cal_type.lower() == "correct":
         with multiprocessing.Pool() as pool:
             result = pool.starmap(validate_h5files, zip(
                 h5files, len(h5files)*[reference_folder]))
     else:  # "dark"
-        validate_files = partial(validate_constant_files, reference_folder, out_folder)  # noqa
+        validate_files = partial(validate_constant_file, reference_folder, out_folder)  # noqa
         with multiprocessing.Pool() as pool:
             result = pool.map(validate_files, h5files)
 
-    for i in result:
-        all_files_validated.append(i[0])
-        if not i[0]:
-            non_valid_files.append(i[1])
-    assert all(all_files_validated), f"{test_key} failure, while validating {non_valid_files}"  # noqa
+    for valid, file in result:
+        if not valid:
+            non_valid_files.append(file)
+    assert len(non_valid_files) == 0, f"{test_key} failure, while validating metadata for {non_valid_files}"  # noqa
     print(f"{test_key}'s calibration h5files are validated successfully.")
-- 
GitLab