oml-plot-tools 0.9.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- oml_plot_tools/__init__.py +24 -0
- oml_plot_tools/common.py +172 -0
- oml_plot_tools/consum.py +187 -0
- oml_plot_tools/main.py +49 -0
- oml_plot_tools/radio.py +184 -0
- oml_plot_tools/tests/__init__.py +22 -0
- oml_plot_tools/tests/common.py +126 -0
- oml_plot_tools/tests/common_test.py +133 -0
- oml_plot_tools/tests/consum_test.py +201 -0
- oml_plot_tools/tests/examples/consumption.oml +4179 -0
- oml_plot_tools/tests/examples/consumption_all.png +0 -0
- oml_plot_tools/tests/examples/consumption_clock.png +0 -0
- oml_plot_tools/tests/examples/consumption_current.png +0 -0
- oml_plot_tools/tests/examples/consumption_only_one.oml +10 -0
- oml_plot_tools/tests/examples/grenoble-iotlab.png +0 -0
- oml_plot_tools/tests/examples/radio.oml +2009 -0
- oml_plot_tools/tests/examples/radio_clock.png +0 -0
- oml_plot_tools/tests/examples/radio_separated_last.png +0 -0
- oml_plot_tools/tests/examples/radio_single.png +0 -0
- oml_plot_tools/tests/examples/robot.oml +1447 -0
- oml_plot_tools/tests/examples/trajectory_all.png +0 -0
- oml_plot_tools/tests/examples/trajectory_angle.png +0 -0
- oml_plot_tools/tests/examples/trajectory_circuit.png +0 -0
- oml_plot_tools/tests/examples/trajectory_clock.png +0 -0
- oml_plot_tools/tests/examples/trajectory_only.png +0 -0
- oml_plot_tools/tests/main_parser_test.py +51 -0
- oml_plot_tools/tests/radio_test.py +173 -0
- oml_plot_tools/tests/traj_test.py +223 -0
- oml_plot_tools/traj.py +352 -0
- oml_plot_tools-0.9.1.dist-info/METADATA +35 -0
- oml_plot_tools-0.9.1.dist-info/RECORD +35 -0
- oml_plot_tools-0.9.1.dist-info/WHEEL +4 -0
- oml_plot_tools-0.9.1.dist-info/entry_points.txt +5 -0
- oml_plot_tools-0.9.1.dist-info/licenses/AUTHORS +1 -0
- oml_plot_tools-0.9.1.dist-info/licenses/COPYING +518 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# -*- coding:utf-8 -*-
|
|
2
|
+
|
|
3
|
+
# This file is a part of IoT-LAB oml-plot-tools
|
|
4
|
+
# Copyright (C) 2015 INRIA (Contact: admin@iot-lab.info)
|
|
5
|
+
# Contributor(s) : see AUTHORS file
|
|
6
|
+
#
|
|
7
|
+
# This software is governed by the CeCILL license under French law
|
|
8
|
+
# and abiding by the rules of distribution of free software. You can use,
|
|
9
|
+
# modify and/ or redistribute the software under the terms of the CeCILL
|
|
10
|
+
# license as circulated by CEA, CNRS and INRIA at the following URL
|
|
11
|
+
# http://www.cecill.info.
|
|
12
|
+
#
|
|
13
|
+
# As a counterpart to the access to the source code and rights to copy,
|
|
14
|
+
# modify and redistribute granted by the license, users are provided only
|
|
15
|
+
# with a limited warranty and the software's author, the holder of the
|
|
16
|
+
# economic rights, and the successive licensors have only limited
|
|
17
|
+
# liability.
|
|
18
|
+
#
|
|
19
|
+
# The fact that you are presently reading this means that you have had
|
|
20
|
+
# knowledge of the CeCILL license and that you accept its terms.
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
"""Common tests functions."""
|
|
24
|
+
|
|
25
|
+
import math
|
|
26
|
+
import os
|
|
27
|
+
import runpy
|
|
28
|
+
import sys
|
|
29
|
+
from io import StringIO
|
|
30
|
+
from unittest import mock
|
|
31
|
+
|
|
32
|
+
import matplotlib.pyplot as plt
|
|
33
|
+
from PIL import Image
|
|
34
|
+
|
|
35
|
+
TEST_DIR = os.path.dirname(__file__)
|
|
36
|
+
IS_PYTHON_3_10 = (3, 10) == tuple(map(int, sys.version.split()[0].split(".")))[:2]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def fixture_path(*args):
|
|
40
|
+
"""Test file path."""
|
|
41
|
+
return os.path.join(TEST_DIR, *args)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def help_main_and_doc(module, help_opt="--help"):
|
|
45
|
+
"""Check that help message is module docstring.
|
|
46
|
+
|
|
47
|
+
Force COLUMNS to 80 as argparse wraps its usage line on the terminal
|
|
48
|
+
width, while the docstrings are written for the default 80 columns.
|
|
49
|
+
"""
|
|
50
|
+
if not hasattr(module, "main"):
|
|
51
|
+
return None, None # pragma: no cover
|
|
52
|
+
|
|
53
|
+
help_args = [module.__name__, help_opt]
|
|
54
|
+
out_msg = StringIO()
|
|
55
|
+
|
|
56
|
+
with mock.patch.dict(os.environ, {"COLUMNS": "80"}):
|
|
57
|
+
with mock.patch("sys.argv", help_args):
|
|
58
|
+
with mock.patch("sys.stderr", out_msg):
|
|
59
|
+
with mock.patch("sys.stdout", out_msg):
|
|
60
|
+
try:
|
|
61
|
+
runpy.run_module(
|
|
62
|
+
module.__name__, run_name="__main__", alter_sys=True
|
|
63
|
+
)
|
|
64
|
+
except SystemExit:
|
|
65
|
+
pass
|
|
66
|
+
|
|
67
|
+
help_msg = out_msg.getvalue().strip()
|
|
68
|
+
help_doc = module.__doc__.strip()
|
|
69
|
+
print(help_msg)
|
|
70
|
+
print(help_doc)
|
|
71
|
+
|
|
72
|
+
return help_msg, help_doc
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def utest_help_as_doc(testcase_instance, module, *args, **kwargs):
|
|
76
|
+
"""Run help_as_doc as unittest test."""
|
|
77
|
+
help_msg, help_doc = help_main_and_doc(module, *args, **kwargs)
|
|
78
|
+
testcase_instance.assertEqual(help_msg, help_doc)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def compare_images(ref_img, tmp_img):
|
|
82
|
+
"""Compare two images using PIL.
|
|
83
|
+
|
|
84
|
+
:returns: root-mean-square of the two images
|
|
85
|
+
"""
|
|
86
|
+
ref_h = Image.open(ref_img).histogram()
|
|
87
|
+
tmp_h = Image.open(tmp_img).histogram()
|
|
88
|
+
rms = math.sqrt(sum((a - b) ** 2 for a, b in zip(ref_h, tmp_h)) / len(ref_h))
|
|
89
|
+
return rms
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def utest_plot_and_compare(testcase, ref_img, threshold=0.0):
|
|
93
|
+
"""Plot image and compare files.
|
|
94
|
+
|
|
95
|
+
Keep file if they differ.
|
|
96
|
+
'savefig' is not determinist between hosts so allow some differences with
|
|
97
|
+
threshold.
|
|
98
|
+
"""
|
|
99
|
+
tmp_img = os.path.join("/tmp", os.path.basename(ref_img))
|
|
100
|
+
|
|
101
|
+
plt.tight_layout()
|
|
102
|
+
plt.savefig(tmp_img)
|
|
103
|
+
|
|
104
|
+
rms = compare_images(ref_img, tmp_img)
|
|
105
|
+
|
|
106
|
+
msg = f"{ref_img} != {tmp_img}: Root-mean-square == {rms:f} > {threshold:f}"
|
|
107
|
+
testcase.assertTrue(rms <= threshold, msg=msg)
|
|
108
|
+
|
|
109
|
+
os.remove(tmp_img)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def assert_called_with_nparray(mock_function, np_array, *args, **kwargs):
|
|
113
|
+
"""Assert mock function has been called with given np_array and arguments.
|
|
114
|
+
|
|
115
|
+
Using default mock assert_called_with failed.
|
|
116
|
+
Also using numpy comparison functions did not return expected value so use
|
|
117
|
+
'repr'
|
|
118
|
+
"""
|
|
119
|
+
call_args, call_kwargs = mock_function.call_args
|
|
120
|
+
|
|
121
|
+
call_array = call_args[0]
|
|
122
|
+
call_args = call_args[1:]
|
|
123
|
+
|
|
124
|
+
assert repr(call_array) == repr(np_array)
|
|
125
|
+
assert repr(call_args) == repr(args)
|
|
126
|
+
assert call_kwargs == kwargs
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
# This file is a part of IoT-LAB oml-plot-tools
|
|
4
|
+
# Copyright (C) 2015 INRIA (Contact: admin@iot-lab.info)
|
|
5
|
+
# Contributor(s) : see AUTHORS file
|
|
6
|
+
#
|
|
7
|
+
# This software is governed by the CeCILL license under French law
|
|
8
|
+
# and abiding by the rules of distribution of free software. You can use,
|
|
9
|
+
# modify and/ or redistribute the software under the terms of the CeCILL
|
|
10
|
+
# license as circulated by CEA, CNRS and INRIA at the following URL
|
|
11
|
+
# http://www.cecill.info.
|
|
12
|
+
#
|
|
13
|
+
# As a counterpart to the access to the source code and rights to copy,
|
|
14
|
+
# modify and redistribute granted by the license, users are provided only
|
|
15
|
+
# with a limited warranty and the software's author, the holder of the
|
|
16
|
+
# economic rights, and the successive licensors have only limited
|
|
17
|
+
# liability.
|
|
18
|
+
#
|
|
19
|
+
# The fact that you are presently reading this means that you have had
|
|
20
|
+
# knowledge of the CeCILL license and that you accept its terms.
|
|
21
|
+
|
|
22
|
+
"""Tests for common.py."""
|
|
23
|
+
|
|
24
|
+
import unittest
|
|
25
|
+
from io import StringIO
|
|
26
|
+
|
|
27
|
+
import numpy
|
|
28
|
+
|
|
29
|
+
from oml_plot_tools import common, consum
|
|
30
|
+
|
|
31
|
+
MEASURE_FMT = "{t} {type} {num} {t_s} {t_us} {measures}\n"
|
|
32
|
+
HEADER = "HEADER\n" * common.OML_HEADER_LEN
|
|
33
|
+
CONSO_T = common.OML_TYPES["consumption"]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class TestCommon(unittest.TestCase):
|
|
37
|
+
"""Tests for common OML loading utilities."""
|
|
38
|
+
|
|
39
|
+
def test_oml_load(self):
|
|
40
|
+
"""Test loading valid OML data with two measurement entries."""
|
|
41
|
+
meas = "1. 2. 3."
|
|
42
|
+
content = HEADER
|
|
43
|
+
content += MEASURE_FMT.format(
|
|
44
|
+
t=0.1234, type=CONSO_T, num=1, t_s=12345, t_us=678900, measures=meas
|
|
45
|
+
)
|
|
46
|
+
content += MEASURE_FMT.format(
|
|
47
|
+
t=1.1234, type=CONSO_T, num=2, t_s=12346, t_us=678900, measures=meas
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
ret = common.oml_load(
|
|
51
|
+
StringIO(content), "consumption", consum.MEASURES_D.values()
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
expected = [
|
|
55
|
+
(12345.6789, "consumption", 1, 12345, 678900, 1.0, 2.0, 3.0),
|
|
56
|
+
(12346.6789, "consumption", 2, 12346, 678900, 1.0, 2.0, 3.0),
|
|
57
|
+
]
|
|
58
|
+
self.assertEqual(expected, ret.tolist())
|
|
59
|
+
self.assertTrue(isinstance(ret, numpy.ndarray))
|
|
60
|
+
|
|
61
|
+
def test_oml_load_only_one(self):
|
|
62
|
+
"""Test loading valid OML data with a single measurement entry."""
|
|
63
|
+
meas = "1. 2. 3."
|
|
64
|
+
content = HEADER
|
|
65
|
+
content += MEASURE_FMT.format(
|
|
66
|
+
t=0.1234, type=CONSO_T, num=1, t_s=12345, t_us=678900, measures=meas
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
ret = common.oml_load(
|
|
70
|
+
StringIO(content), "consumption", consum.MEASURES_D.values()
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
expected = [(12345.6789, "consumption", 1, 12345, 678900, 1.0, 2.0, 3.0)]
|
|
74
|
+
self.assertEqual(expected, ret.tolist())
|
|
75
|
+
self.assertTrue(isinstance(ret, numpy.ndarray))
|
|
76
|
+
|
|
77
|
+
def test_oml_invalid(self):
|
|
78
|
+
"""Test that loading invalid or malformed OML data raises ValueError."""
|
|
79
|
+
# invalid data
|
|
80
|
+
content = HEADER + "invalid_content"
|
|
81
|
+
self.assertRaises(
|
|
82
|
+
ValueError,
|
|
83
|
+
common.oml_load,
|
|
84
|
+
StringIO(content),
|
|
85
|
+
"consumption",
|
|
86
|
+
consum.MEASURES_D.values(),
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
# Unknown file path
|
|
90
|
+
self.assertRaises(
|
|
91
|
+
ValueError,
|
|
92
|
+
common.oml_load,
|
|
93
|
+
"/invalid/file/path",
|
|
94
|
+
"consumption",
|
|
95
|
+
consum.MEASURES_D.values(),
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
# skip header fail
|
|
99
|
+
self.assertRaises(
|
|
100
|
+
ValueError,
|
|
101
|
+
common.oml_load,
|
|
102
|
+
StringIO("1 2 3"),
|
|
103
|
+
"consumption",
|
|
104
|
+
consum.MEASURES_D.values(),
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
# invalid oml 'type' file
|
|
108
|
+
meas = "1. 2. 3."
|
|
109
|
+
content = HEADER
|
|
110
|
+
content += MEASURE_FMT.format(
|
|
111
|
+
t=0.1234, type=(CONSO_T + 1), num=1, t_s=12345, t_us=678900, measures=meas
|
|
112
|
+
)
|
|
113
|
+
self.assertRaises(
|
|
114
|
+
ValueError,
|
|
115
|
+
common.oml_load,
|
|
116
|
+
StringIO(content),
|
|
117
|
+
"consumption",
|
|
118
|
+
consum.MEASURES_D.values(),
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
def test_array_empty(self):
|
|
122
|
+
"""Test the array_empty utility function."""
|
|
123
|
+
self.assertTrue(common.array_empty(None))
|
|
124
|
+
self.assertTrue(common.array_empty([]))
|
|
125
|
+
self.assertFalse(common.array_empty([1, 2, 3]))
|
|
126
|
+
|
|
127
|
+
def test_measures_dict(self):
|
|
128
|
+
"""Test the measures_dict utility function."""
|
|
129
|
+
d = common.measures_dict(("power", float, "Power (W)"))
|
|
130
|
+
self.assertIn("power", d)
|
|
131
|
+
self.assertEqual(d["power"].name, "power")
|
|
132
|
+
self.assertEqual(d["power"].type, float)
|
|
133
|
+
self.assertEqual(d["power"].label, "Power (W)")
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
# This file is a part of IoT-LAB oml-plot-tools
|
|
4
|
+
# Copyright (C) 2015 INRIA (Contact: admin@iot-lab.info)
|
|
5
|
+
# Contributor(s) : see AUTHORS file
|
|
6
|
+
#
|
|
7
|
+
# This software is governed by the CeCILL license under French law
|
|
8
|
+
# and abiding by the rules of distribution of free software. You can use,
|
|
9
|
+
# modify and/ or redistribute the software under the terms of the CeCILL
|
|
10
|
+
# license as circulated by CEA, CNRS and INRIA at the following URL
|
|
11
|
+
# http://www.cecill.info.
|
|
12
|
+
#
|
|
13
|
+
# As a counterpart to the access to the source code and rights to copy,
|
|
14
|
+
# modify and redistribute granted by the license, users are provided only
|
|
15
|
+
# with a limited warranty and the software's author, the holder of the
|
|
16
|
+
# economic rights, and the successive licensors have only limited
|
|
17
|
+
# liability.
|
|
18
|
+
#
|
|
19
|
+
# The fact that you are presently reading this means that you have had
|
|
20
|
+
# knowledge of the CeCILL license and that you accept its terms.
|
|
21
|
+
|
|
22
|
+
"""Tests for consum.py."""
|
|
23
|
+
|
|
24
|
+
import unittest
|
|
25
|
+
from unittest import mock
|
|
26
|
+
|
|
27
|
+
from .. import common, consum
|
|
28
|
+
from .common import (
|
|
29
|
+
IS_PYTHON_3_10,
|
|
30
|
+
assert_called_with_nparray,
|
|
31
|
+
fixture_path,
|
|
32
|
+
utest_help_as_doc,
|
|
33
|
+
utest_plot_and_compare,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class TestConsumptionOmlPlot(unittest.TestCase):
|
|
38
|
+
"""Tests for consumption OML plot functions."""
|
|
39
|
+
|
|
40
|
+
def setUp(self):
|
|
41
|
+
"""Set up consumption OML data for plot tests."""
|
|
42
|
+
conso_file = fixture_path("examples", "consumption.oml")
|
|
43
|
+
self.data = consum.oml_load(conso_file)
|
|
44
|
+
self.title = "Node"
|
|
45
|
+
|
|
46
|
+
def test_plot_all(self):
|
|
47
|
+
"""Test plotting all consumption measures."""
|
|
48
|
+
ref_img = fixture_path("examples", "consumption_all.png")
|
|
49
|
+
consum.oml_plot(self.data, self.title, consum.MEASURES_D.values())
|
|
50
|
+
utest_plot_and_compare(self, ref_img, 150)
|
|
51
|
+
|
|
52
|
+
def test_plot_current(self):
|
|
53
|
+
"""Test plotting current consumption measure only."""
|
|
54
|
+
ref_img = fixture_path("examples", "consumption_current.png")
|
|
55
|
+
consum.oml_plot(self.data, self.title, [consum.MEASURES_D["current"]])
|
|
56
|
+
utest_plot_and_compare(self, ref_img, 100)
|
|
57
|
+
|
|
58
|
+
def test_plot_clock(self):
|
|
59
|
+
"""Test plotting OML clock data for consumption."""
|
|
60
|
+
ref_img = fixture_path("examples", "consumption_clock.png")
|
|
61
|
+
consum.common.oml_plot_clock(self.data)
|
|
62
|
+
utest_plot_and_compare(self, ref_img, 50)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class TestConsumptionPlot(unittest.TestCase):
|
|
66
|
+
"""Tests for consumption main CLI entry point."""
|
|
67
|
+
|
|
68
|
+
def setUp(self):
|
|
69
|
+
"""Set up mocks and test arguments for consumption main tests."""
|
|
70
|
+
meas_file = fixture_path("examples", "consumption.oml")
|
|
71
|
+
self.data = consum.oml_load(meas_file)[0:1]
|
|
72
|
+
|
|
73
|
+
self.title = "TITLE_TESTS"
|
|
74
|
+
self.args = [
|
|
75
|
+
"plot_oml_consum",
|
|
76
|
+
"-i",
|
|
77
|
+
meas_file,
|
|
78
|
+
"--begin",
|
|
79
|
+
"0",
|
|
80
|
+
"--end",
|
|
81
|
+
"1",
|
|
82
|
+
"-l",
|
|
83
|
+
self.title,
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
self.oml_plot = mock.patch("oml_plot_tools.consum.oml_plot").start()
|
|
87
|
+
self.oml_plot_clock = mock.patch(
|
|
88
|
+
"oml_plot_tools.consum.common.oml_plot_clock"
|
|
89
|
+
).start()
|
|
90
|
+
|
|
91
|
+
def tearDown(self):
|
|
92
|
+
"""Stop all active patches after each test."""
|
|
93
|
+
mock.patch.stopall()
|
|
94
|
+
|
|
95
|
+
def consum_main(self, *args):
|
|
96
|
+
"""Call consumption main with given additional args."""
|
|
97
|
+
with mock.patch("sys.argv", list(self.args) + list(args)):
|
|
98
|
+
consum.main()
|
|
99
|
+
|
|
100
|
+
def test_plot_selection(self):
|
|
101
|
+
"""Test individual measure selection options -p, -v, -c."""
|
|
102
|
+
self.consum_main("-p")
|
|
103
|
+
assert_called_with_nparray(
|
|
104
|
+
self.oml_plot,
|
|
105
|
+
self.data,
|
|
106
|
+
self.title,
|
|
107
|
+
[common.MeasureTuple("power", float, "Power (W)")],
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
self.consum_main("-v")
|
|
111
|
+
assert_called_with_nparray(
|
|
112
|
+
self.oml_plot,
|
|
113
|
+
self.data,
|
|
114
|
+
self.title,
|
|
115
|
+
[common.MeasureTuple("voltage", float, "Voltage (V)")],
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
self.consum_main("-c")
|
|
119
|
+
assert_called_with_nparray(
|
|
120
|
+
self.oml_plot,
|
|
121
|
+
self.data,
|
|
122
|
+
self.title,
|
|
123
|
+
[common.MeasureTuple("current", float, "Current (A)")],
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
self.oml_plot.reset_mock()
|
|
127
|
+
self.consum_main("-c", "-v", "-p", "-p")
|
|
128
|
+
self.assertEqual(self.oml_plot.call_count, 3)
|
|
129
|
+
|
|
130
|
+
def test_plot_all(self):
|
|
131
|
+
"""Test -a option calls oml_plot with all measures."""
|
|
132
|
+
self.consum_main("-a")
|
|
133
|
+
assert_called_with_nparray(
|
|
134
|
+
self.oml_plot, self.data, self.title, consum.MEASURES_D.values()
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
def test_plot_default_all(self):
|
|
138
|
+
"""Test that no measure option defaults to plotting all measures."""
|
|
139
|
+
self.consum_main()
|
|
140
|
+
assert_called_with_nparray(
|
|
141
|
+
self.oml_plot, self.data, self.title, consum.MEASURES_D.values()
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
def test_plot_time(self):
|
|
145
|
+
"""Test -t option calls oml_plot_clock with consumption data."""
|
|
146
|
+
self.consum_main("-t")
|
|
147
|
+
assert_called_with_nparray(self.oml_plot_clock, self.data)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class TestConsumptionPlotDirect(unittest.TestCase):
|
|
151
|
+
"""Tests for direct calls to consumption OML loading and plotting."""
|
|
152
|
+
|
|
153
|
+
def setUp(self):
|
|
154
|
+
"""Set up test OML data for direct loading and plotting tests."""
|
|
155
|
+
meas_file = fixture_path("examples", "consumption.oml")
|
|
156
|
+
self.data = consum.oml_load(meas_file)
|
|
157
|
+
self.title = "Node"
|
|
158
|
+
|
|
159
|
+
def test_consumption_plot_all(self):
|
|
160
|
+
"""Test direct call to consumption_plot with all measures."""
|
|
161
|
+
with mock.patch("oml_plot_tools.consum.oml_plot") as mock_plot:
|
|
162
|
+
with mock.patch("oml_plot_tools.consum.common.plot_show"):
|
|
163
|
+
consum.consumption_plot(self.data, self.title, ["all"])
|
|
164
|
+
self.assertTrue(mock_plot.called)
|
|
165
|
+
|
|
166
|
+
def test_consumption_plot_power(self):
|
|
167
|
+
"""Test direct call to consumption_plot with power measure."""
|
|
168
|
+
with mock.patch("oml_plot_tools.consum.oml_plot") as mock_plot:
|
|
169
|
+
with mock.patch("oml_plot_tools.consum.common.plot_show"):
|
|
170
|
+
consum.consumption_plot(self.data, self.title, ["power"])
|
|
171
|
+
self.assertTrue(mock_plot.called)
|
|
172
|
+
|
|
173
|
+
def test_consumption_plot_voltage(self):
|
|
174
|
+
"""Test direct call to consumption_plot with voltage measure."""
|
|
175
|
+
with mock.patch("oml_plot_tools.consum.oml_plot") as mock_plot:
|
|
176
|
+
with mock.patch("oml_plot_tools.consum.common.plot_show"):
|
|
177
|
+
consum.consumption_plot(self.data, self.title, ["voltage"])
|
|
178
|
+
self.assertTrue(mock_plot.called)
|
|
179
|
+
|
|
180
|
+
def test_consumption_plot_current(self):
|
|
181
|
+
"""Test direct call to consumption_plot with current measure."""
|
|
182
|
+
with mock.patch("oml_plot_tools.consum.oml_plot") as mock_plot:
|
|
183
|
+
with mock.patch("oml_plot_tools.consum.common.plot_show"):
|
|
184
|
+
consum.consumption_plot(self.data, self.title, ["current"])
|
|
185
|
+
self.assertTrue(mock_plot.called)
|
|
186
|
+
|
|
187
|
+
def test_consumption_plot_time(self):
|
|
188
|
+
"""Test direct call to consumption_plot with time measure."""
|
|
189
|
+
with mock.patch("oml_plot_tools.consum.common.oml_plot_clock") as mock_clock:
|
|
190
|
+
with mock.patch("oml_plot_tools.consum.common.plot_show"):
|
|
191
|
+
consum.consumption_plot(self.data, self.title, ["time"])
|
|
192
|
+
self.assertTrue(mock_clock.called)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
class TestDoc(unittest.TestCase):
|
|
196
|
+
"""Tests that module help matches its docstring."""
|
|
197
|
+
|
|
198
|
+
@unittest.skipIf(IS_PYTHON_3_10, "Python 3.10 not supported")
|
|
199
|
+
def test_doc(self):
|
|
200
|
+
"""Test that the module help output matches its docstring."""
|
|
201
|
+
utest_help_as_doc(self, consum)
|