Skip to content

Commit 4f6fa8d

Browse files
Merge pull request #38 from Riscure/ease-of-use-improvements
Ease of use improvements
2 parents d27cf28 + a422c0b commit 4f6fa8d

File tree

10 files changed

+512
-59
lines changed

10 files changed

+512
-59
lines changed

tests/test_creation.py

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import shutil
88

99
from trsfile import Trace, SampleCoding, Header, TracePadding
10-
from trsfile.parametermap import TraceParameterMap, TraceParameterDefinitionMap, TraceSetParameterMap
10+
from trsfile.parametermap import TraceParameterMap, TraceParameterDefinitionMap, TraceSetParameterMap, RawTraceData
1111
from trsfile.standardparameters import StandardTraceSetParameters
1212
from trsfile.traceparameter import ByteArrayParameter, TraceParameterDefinition, ParameterType, StringParameter, \
1313
IntegerArrayParameter, BooleanArrayParameter, FloatArrayParameter
@@ -178,6 +178,20 @@ def test_header_to_trace_set_params(self):
178178
except Exception as e:
179179
self.fail('Exception occurred: ' + str(e))
180180

181+
def test_write_different_trace_sizes(self):
182+
trace_count = 100
183+
sample_count = 1000
184+
185+
with trsfile.open(self.tmp_path, 'w', padding_mode=TracePadding.AUTO) as trs_traces:
186+
trs_traces.extend([
187+
Trace(
188+
SampleCoding.FLOAT,
189+
[0] * sample_count,
190+
RawTraceData(i.to_bytes(8, byteorder='big'))
191+
)
192+
for i in range(0, trace_count)]
193+
)
194+
181195
def test_write_closed(self):
182196
trace_count = 100
183197
sample_count = 1000
@@ -196,6 +210,75 @@ def test_write_closed(self):
196210
with self.assertRaises(ValueError):
197211
print(trs_traces)
198212

213+
def test_write_different_trace_sizes(self):
214+
trace_count = 100
215+
sample_count = 1000
216+
217+
with trsfile.open(self.tmp_path, 'w', padding_mode=TracePadding.AUTO) as trs_traces:
218+
trs_traces.extend([
219+
Trace(
220+
SampleCoding.FLOAT,
221+
[0] * sample_count,
222+
TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(i.to_bytes(8, byteorder='big'))})
223+
)
224+
for i in range(0, trace_count)]
225+
)
226+
with self.assertRaises(TypeError):
227+
# The length is incorrect
228+
# Should raise a Type error: The parameters of trace #0 do not match the trace set's definitions.
229+
trs_traces.extend([
230+
Trace(
231+
SampleCoding.FLOAT,
232+
[0] * sample_count,
233+
TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(bytes.fromhex('cafebabedeadbeef0102030405060708'))})
234+
)]
235+
)
236+
with self.assertRaises(TypeError):
237+
# The name is incorrect
238+
# Should raise a Type error: The parameters of trace #1 do not match the trace set's definitions.
239+
trs_traces.extend([
240+
Trace(
241+
SampleCoding.FLOAT,
242+
[0] * sample_count,
243+
TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(bytes.fromhex('0102030405060708'))})
244+
),
245+
Trace(
246+
SampleCoding.FLOAT,
247+
[0] * sample_count,
248+
TraceParameterMap({'NEW_DATA': ByteArrayParameter(bytes.fromhex('0102030405060708'))})
249+
)]
250+
)
251+
with self.assertRaises(TypeError):
252+
# The type is incorrect
253+
# Should raise a Type error: The parameters of trace #0 do not match the trace set's definitions.
254+
trs_traces.extend([
255+
Trace(
256+
SampleCoding.FLOAT,
257+
[0] * sample_count,
258+
TraceParameterMap({'LEGACY_DATA': IntegerArrayParameter([42, 74])})
259+
)]
260+
)
261+
262+
with trsfile.open(self.tmp_path, 'w', padding_mode=TracePadding.AUTO) as trs_traces:
263+
trs_traces.extend([
264+
Trace(
265+
SampleCoding.FLOAT,
266+
[0] * sample_count,
267+
TraceParameterMap()
268+
)
269+
for i in range(0, trace_count)]
270+
)
271+
with self.assertRaises(TypeError):
272+
# The length, data and name are incorrect
273+
# Should raise a Type error: The parameters of trace #0 do not match the trace set's definitions.
274+
trs_traces.extend([
275+
Trace(
276+
SampleCoding.FLOAT,
277+
[0] * sample_count,
278+
TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(bytes.fromhex('cafebabedeadbeef0102030405060708'))})
279+
)]
280+
)
281+
199282
def test_read(self):
200283
trace_count = 100
201284
sample_count = 1000
@@ -270,7 +353,7 @@ def test_append(self):
270353
Trace(
271354
SampleCoding.FLOAT,
272355
[0] * sample_count,
273-
TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(i.to_bytes(8, byteorder='big'))})
356+
raw_data=i.to_bytes(8, byteorder='big')
274357
)
275358
for i in range(0, trace_count)]
276359
)

tests/test_header.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ def test_trace_param_defs_append_errors(self):
9090
trace_parameter_definitions.popitem()
9191
with self.assertRaises(TypeError):
9292
trace_parameter_definitions.clear()
93+
with self.assertRaises(TypeError):
94+
trace_parameter_definitions.append('input', ParameterType.BYTE, 16)
95+
with self.assertRaises(TypeError):
96+
trace_parameter_definitions.insert('output', ParameterType.BYTE, 16, 0)
9397

9498
# Shallow copies still share references to the same trace set parameters as the original,
9599
# and should therefore not be modifiable if the original isn't

tests/test_parameter.py

Lines changed: 113 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
from io import BytesIO
22
from unittest import TestCase
33

4+
from numpy import ndarray, int16, array, int32, int64, single, double, uint8, int8, uint16, bool8
5+
46
from trsfile.traceparameter import BooleanArrayParameter, ByteArrayParameter, DoubleArrayParameter, FloatArrayParameter, \
57
IntegerArrayParameter, ShortArrayParameter, LongArrayParameter, StringParameter
68

79

810
class TestParameter(TestCase):
911
def test_bool_parameter(self):
1012
serialized_param = b'\x01\x00\x01'
11-
param = BooleanArrayParameter([True, False, True])
12-
self.assertEqual(serialized_param, param.serialize())
13-
self.assertEqual(BooleanArrayParameter.deserialize(BytesIO(serialized_param), 3), param)
13+
param1 = BooleanArrayParameter([True, False, True])
14+
self.assertEqual(serialized_param, param1.serialize())
15+
self.assertEqual(BooleanArrayParameter.deserialize(BytesIO(serialized_param), 3), param1)
16+
param2 = BooleanArrayParameter(ndarray(shape=[3], dtype=bool8,
17+
buffer=array([bool8(val) for val in [True, False, True]])))
18+
self.assertEqual(param1, param2)
1419

1520
with self.assertRaises(TypeError):
1621
BooleanArrayParameter(True)
@@ -27,6 +32,11 @@ def test_byte_parameter(self):
2732
self.assertEqual(serialized_param, param1.serialize())
2833
self.assertEqual(ByteArrayParameter.deserialize(BytesIO(serialized_param), 16), param1)
2934

35+
with self.assertWarns(UserWarning):
36+
param2 = ByteArrayParameter(ndarray(shape=[2, 2, 4], dtype=uint8,
37+
buffer=array([uint8(val) for val in int_data])))
38+
self.assertEqual(param1, param2)
39+
3040
param2 = ByteArrayParameter(bytearray(int_data))
3141
self.assertEqual(param1, param2)
3242

@@ -37,8 +47,14 @@ def test_byte_parameter(self):
3747
ByteArrayParameter([0, '1'])
3848
with self.assertRaises(TypeError):
3949
ByteArrayParameter([bytes([0, 1, 2, 3]), bytes([4, 5, 6, 7])])
50+
with self.assertRaises(TypeError):
51+
ByteArrayParameter(ndarray(shape=[16], dtype=int8, buffer=array([int8(val) for val in int_data])))
52+
with self.assertRaises(TypeError):
53+
ByteArrayParameter(ndarray(shape=[16], dtype=uint16, buffer=array([uint16(val) for val in int_data])))
4054
with self.assertRaises(ValueError):
4155
ByteArrayParameter([])
56+
with self.assertRaises(ValueError):
57+
ByteArrayParameter(ndarray(shape=[0], dtype=uint8, buffer=array([])))
4258
with self.assertRaises(TypeError):
4359
ByteArrayParameter([0, 1, 2, -1])
4460
with self.assertRaises(TypeError):
@@ -47,13 +63,26 @@ def test_byte_parameter(self):
4763
def test_double_parameter(self):
4864
serialized_param = b'\x00\x00\x00\x00\x00\x00\xe0\xbf\x00\x00\x00\x00\x00\x00\xe0\x3f' \
4965
b'\x00\x00\x00\x00\x80\x84\x2e\x41'
50-
param = DoubleArrayParameter([-0.5, 0.5, 1e6])
51-
self.assertEqual(serialized_param, param.serialize())
52-
self.assertEqual(DoubleArrayParameter.deserialize(BytesIO(serialized_param), 3), param)
66+
param1 = DoubleArrayParameter([-0.5, 0.5, 1e6])
67+
self.assertEqual(serialized_param, param1.serialize())
68+
self.assertEqual(DoubleArrayParameter.deserialize(BytesIO(serialized_param), 3), param1)
69+
70+
param2 = DoubleArrayParameter(ndarray(shape=[3], dtype=double, buffer=array([-0.5, 0.5, 1e6])))
71+
self.assertEqual(param1, param2)
5372

5473
# an array of only integers is still a valid value of a DoubleArrayParameter
55-
param1 = DoubleArrayParameter([1, 2, 1000000])
56-
param2 = DoubleArrayParameter([1, 2.0, 1e6])
74+
param1 = DoubleArrayParameter([-1, 2, 1000000])
75+
param2 = DoubleArrayParameter([-1, 2.0, 1e6])
76+
self.assertEqual(param1, param2)
77+
with self.assertWarns(UserWarning):
78+
param1 = DoubleArrayParameter(ndarray(shape=[1, 3], dtype=int32,
79+
buffer=array([int32(val) for val in [-1, 2, 1000000]])))
80+
self.assertEqual(param1, param2)
81+
82+
with self.assertWarns(UserWarning):
83+
param1 = DoubleArrayParameter(ndarray(shape=[1, 3], dtype=int64,
84+
buffer=array([int64(val) for val in [-1, 2, 10000000000]])))
85+
param2 = DoubleArrayParameter([-1, 2.0, 1e10])
5786
self.assertEqual(param1, param2)
5887

5988
# a float array parameter is not the same as a double array parameter
@@ -63,42 +92,82 @@ def test_double_parameter(self):
6392

6493
with self.assertRaises(TypeError):
6594
DoubleArrayParameter([0.5, -0.5, 'NaN'])
95+
with self.assertRaises(TypeError):
96+
DoubleArrayParameter(ndarray(shape=[3], dtype=single,
97+
buffer=array([single(val) for val in [-0.5, 0.5, 1e6]])))
6698
with self.assertRaises(TypeError):
6799
DoubleArrayParameter(0.5)
68100
with self.assertRaises(ValueError):
69101
DoubleArrayParameter([])
102+
with self.assertRaises(ValueError):
103+
IntegerArrayParameter(ndarray(shape=[0], dtype=double, buffer=array([])))
70104

71105
def test_float_parameter(self):
72106
serialized_param = b'\x00\x00\x00\xbf\x00\x00\x00\x3f\x00\x24\x74\x49'
73-
param = FloatArrayParameter([-0.5, 0.5, 1e6])
74-
self.assertEqual(serialized_param, param.serialize())
75-
self.assertEqual(FloatArrayParameter.deserialize(BytesIO(serialized_param), 3), param)
107+
param1 = FloatArrayParameter([-0.5, 0.5, 1e6])
108+
self.assertEqual(serialized_param, param1.serialize())
109+
self.assertEqual(FloatArrayParameter.deserialize(BytesIO(serialized_param), 3), param1)
110+
111+
param2 = FloatArrayParameter(ndarray(shape=[3], dtype=single,
112+
buffer=array([single(val) for val in [-0.5, 0.5, 1e6]])))
113+
self.assertEqual(param1, param2)
76114

77115
# an array of only integers is still a valid value of a FloatArrayParameter
78-
param1 = FloatArrayParameter([1, 2, 1000000])
79-
param2 = FloatArrayParameter([1, 2.0, 1e6])
116+
param1 = FloatArrayParameter([-1, 2, 1000000])
117+
param2 = FloatArrayParameter([-1, 2.0, 1e6])
118+
self.assertEqual(param1, param2)
119+
120+
with self.assertWarns(UserWarning):
121+
param1 = FloatArrayParameter(ndarray(shape=[1, 3], dtype=int32,
122+
buffer=array([int32(val) for val in [-1, 2, 1000000]])))
123+
self.assertEqual(param1, param2)
124+
125+
with self.assertWarns(UserWarning):
126+
param1 = FloatArrayParameter(ndarray(shape=[1, 3], dtype=int64,
127+
buffer=array([int64(val) for val in [-1, 2, 10000000000]])))
128+
param2 = FloatArrayParameter([-1, 2.0, 1e10])
80129
self.assertEqual(param1, param2)
81130

82131
with self.assertRaises(TypeError):
83132
FloatArrayParameter([0.5, -0.5, 'NaN'])
133+
with self.assertRaises(TypeError):
134+
FloatArrayParameter(ndarray(shape=[3], dtype=double,
135+
buffer=array([double(val) for val in [-0.5, 0.5, 1e6]])))
84136
with self.assertRaises(TypeError):
85137
FloatArrayParameter(0.5)
86138
with self.assertRaises(ValueError):
87139
FloatArrayParameter([])
140+
with self.assertRaises(ValueError):
141+
IntegerArrayParameter(ndarray(shape=[0], dtype=single, buffer=array([])))
88142

89143
def test_integer_parameter(self):
90144
serialized_param = b'\xff\xff\xff\xff\x01\x00\x00\x00\xff\xff\xff\x7f\x00\x00\x00\x80'
91-
param = IntegerArrayParameter([-1, 1, 0x7fffffff, -0x80000000])
92-
self.assertEqual(serialized_param, param.serialize())
93-
self.assertEqual(IntegerArrayParameter.deserialize(BytesIO(serialized_param), 4), param)
145+
param1 = IntegerArrayParameter([-1, 1, 0x7fffffff, -0x80000000])
146+
self.assertEqual(serialized_param, param1.serialize())
147+
self.assertEqual(IntegerArrayParameter.deserialize(BytesIO(serialized_param), 4), param1)
148+
149+
with self.assertWarns(UserWarning):
150+
param2 = IntegerArrayParameter(ndarray(shape=[2, 2], dtype=int32,
151+
buffer=array([int32(val) for val in [-1, 1, 0x7fffffff, -0x80000000]])))
152+
self.assertEqual(param1, param2)
94153

95154
# a short array parameter is not the same as an int array parameter
96155
param1 = ShortArrayParameter([0, 1, -1, 255, 256, -32768, 32767])
97156
param2 = IntegerArrayParameter([0, 1, -1, 255, 256, -32768, 32767])
98157
self.assertNotEqual(param1, param2)
99158

159+
# verify that an integer array parameter based on a ndarray filled with int16s works
160+
param1 = IntegerArrayParameter(ndarray(shape=[7], dtype=int16,
161+
buffer=array([int16(val) for val in [0, 1, -1, 255, 256, -32768, 32767]])))
162+
self.assertEqual(param1, param2)
163+
100164
with self.assertRaises(TypeError):
101165
IntegerArrayParameter([1, 256, 1.0])
166+
with self.assertRaises(TypeError):
167+
IntegerArrayParameter(ndarray(shape=[4], dtype=int64,
168+
buffer=array([int64(val) for val in [-1, 1, 0x7fffffffffffffff, -0x8000000000000000]])))
169+
with self.assertRaises(ValueError):
170+
IntegerArrayParameter(ndarray(shape=[0], dtype=int32, buffer=array([])))
102171
with self.assertRaises(TypeError):
103172
IntegerArrayParameter(1)
104173
with self.assertRaises(ValueError):
@@ -111,30 +180,52 @@ def test_integer_parameter(self):
111180
def test_long_parameter(self):
112181
serialized_param = b'\xff\xff\xff\xff\xff\xff\xff\xff\x01\x00\x00\x00\x00\x00\x00\x00' \
113182
b'\xff\xff\xff\xff\xff\xff\xff\x7f\x00\x00\x00\x00\x00\x00\x00\x80'
114-
param = LongArrayParameter([-1, 1, 0x7fffffffffffffff, -0x8000000000000000])
115-
self.assertEqual(serialized_param, param.serialize())
116-
self.assertEqual(LongArrayParameter.deserialize(BytesIO(serialized_param), 4), param)
183+
param1= LongArrayParameter([-1, 1, 0x7fffffffffffffff, -0x8000000000000000])
184+
self.assertEqual(serialized_param, param1.serialize())
185+
self.assertEqual(LongArrayParameter.deserialize(BytesIO(serialized_param), 4), param1)
186+
187+
with self.assertWarns(UserWarning):
188+
param2 = LongArrayParameter(ndarray(shape=[2, 2], dtype=int64,
189+
buffer=array([int64(val) for val in [-1, 1, 0x7fffffffffffffff, -0x8000000000000000]])))
190+
self.assertEqual(param1, param2)
117191

118192
# an int array parameter is not the same as a long array parameter
119193
param1 = IntegerArrayParameter([-1, 1, 0x7fffffff, -0x80000000])
120194
param2 = LongArrayParameter([-1, 1, 0x7fffffff, -0x80000000])
121195
self.assertNotEqual(param1, param2)
122196

197+
# verify that a long array parameter based on a ndarray filled with int32s works
198+
with self.assertWarns(UserWarning):
199+
param1 = LongArrayParameter(ndarray(shape=[1, 4], dtype=int32,
200+
buffer=array([int32(val) for val in [-1, 1, 0x7fffffff, -0x80000000]])))
201+
self.assertEqual(param1, param2)
202+
123203
with self.assertRaises(TypeError):
124204
LongArrayParameter([1, 256, 1.0])
125205
with self.assertRaises(TypeError):
126206
LongArrayParameter(1)
127207
with self.assertRaises(ValueError):
128208
LongArrayParameter([])
209+
with self.assertRaises(ValueError):
210+
LongArrayParameter(ndarray(shape=[0], dtype=int64, buffer=array([])))
129211

130212
def test_short_parameter(self):
131213
serialized_param = b'\x00\x00\x01\x00\xff\xff\xff\x00\x00\x01\x00\x80\xff\x7f'
132-
param = ShortArrayParameter([0, 1, -1, 255, 256, -32768, 32767])
133-
self.assertEqual(serialized_param, param.serialize())
134-
self.assertEqual(ShortArrayParameter.deserialize(BytesIO(serialized_param), 7), param)
214+
param1 = ShortArrayParameter([0, 1, -1, 255, 256, -32768, 32767])
215+
self.assertEqual(serialized_param, param1.serialize())
216+
self.assertEqual(ShortArrayParameter.deserialize(BytesIO(serialized_param), 7), param1)
217+
218+
param2 = ShortArrayParameter(ndarray(shape=[7], dtype=int16,
219+
buffer=array([int16(val) for val in [0, 1, -1, 255, 256, -32768, 32767]])))
220+
self.assertEqual(param1, param2)
135221

136222
with self.assertRaises(TypeError):
137223
ShortArrayParameter([1, 256, 1.0])
224+
with self.assertRaises(TypeError):
225+
ShortArrayParameter(ndarray(shape=[4], dtype=int32,
226+
buffer=array([int32(val) for val in [-1, 1, 0x7fffffff, -0x80000000]])))
227+
with self.assertRaises(ValueError):
228+
ShortArrayParameter(ndarray(shape=[0], dtype=int16, buffer=array([])))
138229
with self.assertRaises(TypeError):
139230
ShortArrayParameter(1)
140231
with self.assertRaises(ValueError):
@@ -159,5 +250,3 @@ def test_string_parameter(self):
159250
StringParameter(['The', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy', 'dog'])
160251
with self.assertRaises(ValueError):
161252
StringParameter(None)
162-
163-

0 commit comments

Comments
 (0)