Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/DIRAC/tests/Utilities/plots.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# pylint: disable=protected-access
import glob
import math
import operator
import os
from functools import reduce

from PIL import Image
Expand All @@ -24,3 +26,37 @@ def compare(file1Path, file2Path):
h2 = image2.histogram()
rms = math.sqrt(reduce(operator.add, map(lambda a, b: (a - b) ** 2, h1, h2)) / len(h1))
return rms


def referenceImages(directory, stem):
"""Return every reference image available for a given plot.

The primary reference is ``<stem>.png``. Additional references may be added
as ``<stem>.<tag>.png`` (for example ``histogram1.mpl-3.10.png``) when a new
matplotlib version renders a plot slightly differently. Keeping several
references side by side means a plot is accepted against any supported
plotting-stack version, so an upgrade only needs an extra reference image
rather than replacing the existing one (which would break older versions).

:param str directory: Directory holding the reference images.
:param str stem: Base name of the plot, without extension.
:return: Sorted list of reference image paths.
"""
paths = glob.glob(os.path.join(directory, f"{stem}.png"))
paths += glob.glob(os.path.join(directory, f"{stem}.*.png"))
return sorted(paths)


def compareToReferences(generatedPath, referencePaths):
"""Compare a generated plot against several candidate reference images.

:param str generatedPath: Path to the freshly generated plot.
:param referencePaths: Iterable of reference image paths to compare against.

:return: The smallest RMS obtained against any of the references, so a plot
is accepted as soon as it is identical (rms == 0.0) to one of them.
"""
referencePaths = list(referencePaths)
if not referencePaths:
raise ValueError(f"No reference images provided for {generatedPath}")
return min(compare(generatedPath, reference) for reference in referencePaths)
14 changes: 7 additions & 7 deletions tests/Integration/AccountingSystem/Test_Plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
generateNoDataPlot,
generatePiePlot,
)
from DIRAC.tests.Utilities.plots import compare
from DIRAC.tests.Utilities.plots import compareToReferences, referenceImages

plots_directory = os.path.join(os.path.dirname(__file__), "plots")
filename = "plot.png"
Expand All @@ -25,21 +25,21 @@ def test_histogram():
res = generateHistogram(filename, [2, 2, 3, 4, 5, 5], {})
assert res["OK"] is True

res = compare(filename, os.path.join(plots_directory, "histogram1.png"))
res = compareToReferences(filename, referenceImages(plots_directory, "histogram1"))
assert res == 0.0

res = generateHistogram(
filename, [{"a": [1, 2, 3, 1, 2, 2, 4, 2]}, {"b": [2, 2, 2, 4, 4, 1, 1]}], {"plot_grid": "2:1"}
)
assert res["OK"] is True

res = compare(filename, os.path.join(plots_directory, "histogram2.png"))
res = compareToReferences(filename, referenceImages(plots_directory, "histogram2"))
assert res == 0.0

res = generateHistogram(filename, [{"a": [1]}, {"b": [2, 3, 3, 5, 5]}], {})
assert res["OK"] is True

res = compare(filename, os.path.join(plots_directory, "histogram3.png"))
res = compareToReferences(filename, referenceImages(plots_directory, "histogram3"))
assert res == 0.0


Expand All @@ -50,7 +50,7 @@ def test_piechartplot():
res = generatePiePlot(filename, {"a": 16.0, "b": 56.0, "c": 15, "d": 20}, {})
assert res["OK"] is True

res = compare(filename, os.path.join(plots_directory, "piechart.png"))
res = compareToReferences(filename, referenceImages(plots_directory, "piechart"))
assert res == 0.0


Expand All @@ -61,7 +61,7 @@ def test_nodataplot():

res = generateNoDataPlot(filename, {}, {"title": "Test plot"})
assert res["OK"] is True
res = compare(filename, os.path.join(plots_directory, "nodata.png"))
res = compareToReferences(filename, referenceImages(plots_directory, "nodata"))
assert res == 0.0


Expand All @@ -74,5 +74,5 @@ def test_error():
with open(filename, "wb") as out:
out.write(res)

res = compare(filename, os.path.join(plots_directory, "error.png"))
res = compareToReferences(filename, referenceImages(plots_directory, "error"))
assert res == 0.0
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions tests/Integration/DataManagementSystem/Test_UserMetadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ def test_metaIndex(self):
# meta show
result = self.fc.getMetadataFields()
self.assertTrue(result["OK"])
self.assertDictContainsSubset({"MetaInt6": "INT"}, result["Value"]["FileMetaFields"])
self.assertDictContainsSubset({"TestDirectory6": "INT"}, result["Value"]["DirectoryMetaFields"])
self.assertLessEqual({"MetaInt6": "INT"}.items(), result["Value"]["FileMetaFields"].items())
self.assertLessEqual({"TestDirectory6": "INT"}.items(), result["Value"]["DirectoryMetaFields"].items())

# meta set
metaDict6 = {"MetaInt6": 13}
Expand All @@ -135,15 +135,15 @@ def test_metaIndex(self):
# API call only
result = self.fc.getFileUserMetadata(self.lfn5)
self.assertTrue(result["OK"])
self.assertDictContainsSubset({"MetaInt6": 13}, result["Value"])
self.assertLessEqual({"MetaInt6": 13}.items(), result["Value"].items())
# file: expect a failure
result = self.fc.getDirectoryUserMetadata(self.lfn5)
self.assertFalse(result["OK"])

# directory
result = self.fc.getDirectoryUserMetadata(self.dir5)
self.assertTrue(result["OK"])
self.assertDictContainsSubset({"TestDirectory6": 126}, result["Value"])
self.assertLessEqual({"TestDirectory6": 126}.items(), result["Value"].items())

# finally remove
# meta remove lfn5 MetaInt6
Expand Down
Loading