diff options
| author | J08nY | 2020-03-05 00:43:57 +0100 |
|---|---|---|
| committer | J08nY | 2020-03-05 00:43:57 +0100 |
| commit | 0c3c4a8d6725c01d8c4ba7b4a4e5f43922ec1e65 (patch) | |
| tree | a5531714c910f0a7a42280eb244a21c7787bc4bc | |
| parent | f8345c356e37cb8e277d5bf5262c7cc2e57477bd (diff) | |
| download | pyecsca-0c3c4a8d6725c01d8c4ba7b4a4e5f43922ec1e65.tar.gz pyecsca-0c3c4a8d6725c01d8c4ba7b4a4e5f43922ec1e65.tar.zst pyecsca-0c3c4a8d6725c01d8c4ba7b4a4e5f43922ec1e65.zip | |
| -rw-r--r-- | .coveragerc | 1 | ||||
| -rw-r--r-- | Makefile | 6 | ||||
| -rw-r--r-- | pyecsca/sca/trace/plot.py | 42 | ||||
| -rw-r--r-- | test/plots/.gitignore | 4 | ||||
| -rw-r--r-- | test/sca/test_align.py | 8 | ||||
| -rw-r--r-- | test/sca/test_filter.py | 12 | ||||
| -rw-r--r-- | test/sca/test_match.py | 8 | ||||
| -rw-r--r-- | test/sca/test_plot.py | 29 | ||||
| -rw-r--r-- | test/sca/test_sampling.py | 6 | ||||
| -rw-r--r-- | test/sca/utils.py | 64 |
10 files changed, 136 insertions, 44 deletions
diff --git a/.coveragerc b/.coveragerc index fedfb33..92627e6 100644 --- a/.coveragerc +++ b/.coveragerc @@ -3,6 +3,7 @@ branch = True omit = test/* setup.py + fakesource [report] exclude_lines = @@ -3,15 +3,15 @@ ec.test_params ec.test_key_agreement ec.test_key_generation ec.test_mod ec.test_ ec.test_mult ec.test_naf ec.test_op ec.test_point ec.test_signature SCA_TESTS = sca.test_align sca.test_combine sca.test_edit sca.test_filter sca.test_match sca.test_process \ -sca.test_sampling sca.test_target sca.test_test sca.test_trace sca.test_traceset +sca.test_sampling sca.test_target sca.test_test sca.test_trace sca.test_traceset sca.test_plot TESTS = ${EC_TESTS} ${SCA_TESTS} test: - nose2 -s test -A !slow -C -v ${TESTS} + nose2 -s test -E "not slow and not disabled" -C -v ${TESTS} test-plots: - env PYECSCA_TEST_PLOTS=1 nose2 -s test -A !slow -C -v ${TESTS} + env PYECSCA_TEST_PLOTS=1 nose2 -s test -E "not slow and not disabled" -C -v ${TESTS} test-all: nose2 -s test -C -v ${TESTS} diff --git a/pyecsca/sca/trace/plot.py b/pyecsca/sca/trace/plot.py index e69de29..4d5c6db 100644 --- a/pyecsca/sca/trace/plot.py +++ b/pyecsca/sca/trace/plot.py @@ -0,0 +1,42 @@ +""" +This module provides functions for plotting traces. +""" +from bokeh.io import show, save, export_png, export_svgs +from bokeh.layouts import column +from bokeh.plotting import Figure +from bokeh.resources import CDN +from public import public + +from .trace import Trace + + +@public +def new_figure(): + return Figure() + + +@public +def show_figure(figure: Figure): + show(figure) + + +@public +def save_figure(figure: Figure, fname: str, title: str): + lay = column(figure, sizing_mode='stretch_both') + save(lay, fname, resources=CDN, title=title) + + +@public +def save_figure_png(figure: Figure, fname: str, width: int, height: int): + export_png(figure, fname, height, width) + + +@public +def save_figure_svg(figure: Figure, fname: str): + lay = column(figure, sizing_mode='stretch_both') + export_svgs(lay, fname) + + +@public +def plot_trace(figure: Figure, trace: Trace, **kwargs): + figure.line(range(len(trace)), trace.samples, **kwargs) diff --git a/test/plots/.gitignore b/test/plots/.gitignore index aab52d9..365fb3e 100644 --- a/test/plots/.gitignore +++ b/test/plots/.gitignore @@ -1 +1,3 @@ -*.png
\ No newline at end of file +*.png +*.html +*.svg
\ No newline at end of file diff --git a/test/sca/test_align.py b/test/sca/test_align.py index b595058..f446f17 100644 --- a/test/sca/test_align.py +++ b/test/sca/test_align.py @@ -3,10 +3,10 @@ from unittest import TestCase import numpy as np from pyecsca.sca import align_correlation, align_peaks, align_sad, align_dtw_scale,\ align_dtw, Trace, InspectorTraceSet -from .utils import plot, slow +from .utils import Plottable, slow -class AlignTests(TestCase): +class AlignTests(Plottable): def test_align(self): first_arr = np.array([10, 64, 120, 64, 10, 10, 10, 10, 10], dtype=np.dtype("i1")) @@ -60,7 +60,7 @@ class AlignTests(TestCase): self.assertEqual(np.argmax(result[0].samples), np.argmax(result[1].samples)) self.assertEqual(np.argmax(result[1].samples), np.argmax(result[2].samples)) - plot(self, *result) + self.plot(*result) def test_dtw_align(self): first_arr = np.array([10, 64, 14, 120, 15, 30, 10, 15, 20, 15, 15, 10, 10, 8, 10, 12, 10, 13, 9], dtype=np.dtype("i1")) @@ -73,4 +73,4 @@ class AlignTests(TestCase): self.assertEqual(np.argmax(result[0].samples), np.argmax(result[1].samples)) self.assertEqual(np.argmax(result[1].samples), np.argmax(result[2].samples)) - plot(self, *result) + self.plot(*result) diff --git a/test/sca/test_filter.py b/test/sca/test_filter.py index 73516d8..fda5626 100644 --- a/test/sca/test_filter.py +++ b/test/sca/test_filter.py @@ -2,10 +2,10 @@ from unittest import TestCase import numpy as np from pyecsca.sca import Trace, filter_lowpass, filter_highpass, filter_bandpass, filter_bandstop -from .utils import plot +from .utils import Plottable -class FilterTests(TestCase): +class FilterTests(Plottable): def setUp(self): self._trace = Trace( @@ -16,22 +16,22 @@ class FilterTests(TestCase): result = filter_lowpass(self._trace, 100, 20) self.assertIsNotNone(result) self.assertEqual(len(self._trace.samples), len(result.samples)) - plot(self, self._trace, result) + self.plot(self._trace, result) def test_highpass(self): result = filter_highpass(self._trace, 128, 20) self.assertIsNotNone(result) self.assertEqual(len(self._trace.samples), len(result.samples)) - plot(self, self._trace, result) + self.plot(self._trace, result) def test_bandpass(self): result = filter_bandpass(self._trace, 128, 20, 60) self.assertIsNotNone(result) self.assertEqual(len(self._trace.samples), len(result.samples)) - plot(self, self._trace, result) + self.plot(self._trace, result) def test_bandstop(self): result = filter_bandstop(self._trace, 128, 20, 60) self.assertIsNotNone(result) self.assertEqual(len(self._trace.samples), len(result.samples)) - plot(self, self._trace, result) + self.plot(self._trace, result) diff --git a/test/sca/test_match.py b/test/sca/test_match.py index 549f143..1781d9d 100644 --- a/test/sca/test_match.py +++ b/test/sca/test_match.py @@ -3,10 +3,10 @@ from unittest import TestCase import numpy as np from pyecsca.sca import Trace, match_pattern, match_part, pad -from .utils import plot +from .utils import Plottable -class MatchingTests(TestCase): +class MatchingTests(Plottable): def test_simple_match(self): pattern = Trace(np.array([1, 15, 12, -10, 0, 13, 17, -1, 0], dtype=np.dtype("i1")), None, @@ -16,7 +16,7 @@ class MatchingTests(TestCase): dtype=np.dtype("i1")), None, None, None) filtered = match_part(base, 7, 9) self.assertListEqual(filtered, [7]) - plot(self, base=base, pattern=pad(pattern, (filtered[0], 0))) + self.plot(base=base, pattern=pad(pattern, (filtered[0], 0))) def test_multiple_match(self): pattern = Trace(np.array([1, 15, 12, -10, 0, 13, 17, -1, 0], dtype=np.dtype("i1")), None, @@ -27,4 +27,4 @@ class MatchingTests(TestCase): dtype=np.dtype("i1")), None, None, None) filtered = match_pattern(base, pattern, 0.9) self.assertListEqual(filtered, [7, 19]) - plot(self, base=base, pattern1=pad(pattern, (filtered[0], 0)), pattern2=pad(pattern, (filtered[1], 0))) + self.plot(base=base, pattern1=pad(pattern, (filtered[0], 0)), pattern2=pad(pattern, (filtered[1], 0))) diff --git a/test/sca/test_plot.py b/test/sca/test_plot.py new file mode 100644 index 0000000..d004cf5 --- /dev/null +++ b/test/sca/test_plot.py @@ -0,0 +1,29 @@ +from os import getenv + +import numpy as np + +from pyecsca.sca.trace import Trace +from pyecsca.sca.trace.plot import (new_figure, plot_trace, save_figure, save_figure_png, + save_figure_svg) +from .utils import Plottable, disabled + + +class PlotTests(Plottable): + + def setUp(self) -> None: + self.trace = Trace(np.array([6, 7, 3, -2, 5, 1], dtype=np.dtype("i1")), None, None) + self.fig = new_figure() + plot_trace(self.fig, self.trace) + + def test_html(self): + if getenv("PYECSCA_TEST_PLOTS") is None: + return + save_figure(self.fig, self.get_fname() + ".html", "Trace plot") + + @disabled + def test_png(self): + save_figure_png(self.fig, self.get_fname() + ".png", 1000, 400) + + @disabled + def test_svg(self): + save_figure_svg(self.fig, self.get_fname() + ".svg") diff --git a/test/sca/test_sampling.py b/test/sca/test_sampling.py index c08128c..1af1579 100644 --- a/test/sca/test_sampling.py +++ b/test/sca/test_sampling.py @@ -2,10 +2,10 @@ from unittest import TestCase import numpy as np from pyecsca.sca import Trace, downsample_average, downsample_pick, downsample_decimate -from .utils import plot +from .utils import Plottable -class SamplingTests(TestCase): +class SamplingTests(Plottable): def setUp(self): self._trace = Trace(np.array([20, 40, 50, 50, 10], dtype=np.dtype("i1")), None, None) @@ -34,4 +34,4 @@ class SamplingTests(TestCase): self.assertIsNotNone(result) self.assertIsInstance(result, Trace) self.assertEqual(len(result.samples), 15) - plot(self, trace, result) + self.plot(trace, result) diff --git a/test/sca/utils.py b/test/sca/utils.py index 643ab68..7b3ae97 100644 --- a/test/sca/utils.py +++ b/test/sca/utils.py @@ -1,34 +1,52 @@ -import matplotlib.pyplot as plt -from unittest import TestCase -from pyecsca.sca import Trace -from os.path import join, exists, split from os import mkdir, getenv, getcwd +from os.path import join, exists, split +from unittest import TestCase + +import matplotlib.pyplot as plt +from pyecsca.sca import Trace force_plot = True + def slow(func): func.slow = 1 return func + +def disabled(func): + func.disabled = 1 + return func + + cases = {} -def plot(case: TestCase, *traces: Trace, **kwtraces: Trace): - if not force_plot and getenv("PYECSCA_TEST_PLOTS") is None: - return - fig = plt.figure() - ax = fig.add_subplot(111) - for i, trace in enumerate(traces): - ax.plot(trace.samples, label=str(i)) - for name, trace in kwtraces.items(): - ax.plot(trace.samples, label=name) - ax.legend(loc="best") - if split(getcwd())[1] == "test": - directory = "plots" - else: - directory = join("test", "plots") - if not exists(directory): - mkdir(directory) - case_id = cases.setdefault(case.id(), 0) + 1 - cases[case.id()] = case_id - plt.savefig(join(directory, case.id() + str(case_id) + ".png")) + +class Plottable(TestCase): + + def get_dir(self): + if split(getcwd())[1] == "test": + directory = "plots" + else: + directory = join("test", "plots") + if not exists(directory): + mkdir(directory) + return directory + + def get_fname(self): + directory = self.get_dir() + case_id = cases.setdefault(self.id(), 0) + 1 + cases[self.id()] = case_id + return join(directory, self.id() + str(case_id)) + + def plot(self, *traces: Trace, **kwtraces: Trace): + if not force_plot and getenv("PYECSCA_TEST_PLOTS") is None: + return + fig = plt.figure() + ax = fig.add_subplot(111) + for i, trace in enumerate(traces): + ax.plot(trace.samples, label=str(i)) + for name, trace in kwtraces.items(): + ax.plot(trace.samples, label=name) + ax.legend(loc="best") + plt.savefig(self.get_fname() + ".png") |
