def test_extend(self): trace_count = 100 sample_count = 1000 with trsfile.open(self.tmp_path, 'w', padding_mode=TracePadding.AUTO) as trs_traces: # Extend empty list trs_traces.extend([]) self.assertEqual(len(trs_traces), 0) # Extend non empty list trs_traces.extend([ Trace( SampleCoding.FLOAT, [0] * sample_count, TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(bytes(8))}) ) ] ) self.assertEqual(len(trs_traces), 1) # Extend non empty list trs_traces.extend([ Trace( SampleCoding.FLOAT, [0] * sample_count, TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(i.to_bytes(8, byteorder='big'))}) ) for i in range(0, trace_count)] ) self.assertEqual(len(trs_traces), trace_count + 1)
def test_padding(self): trace_count = 100 sample_count = 1000 fmt = SampleCoding.FLOAT with trsfile.open(self.tmp_path, 'w', padding_mode=TracePadding.AUTO) as trs_traces: # This is the length everything should be padded/clipped to trs_traces.extend( Trace( fmt, b'\xDE' * (sample_count * fmt.size), TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(bytes(8))}) ) ) # Padding mode trs_traces.extend([ Trace( fmt, b'\xDE' * (sample_count + i) * fmt.size, TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(abs(i).to_bytes(8, byteorder='big'))}) ) for i in range(0, -trace_count, -1)] ) # Clipping mode trs_traces.extend([ Trace( fmt, b'\xDE' * (sample_count + i) * fmt.size, TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(i.to_bytes(8, byteorder='big'))}) ) for i in range(0, trace_count)] ) with trsfile.open(self.tmp_path, 'r') as trs_traces: self.assertEqual(len(trs_traces), trace_count * 2 + 1) # Check that all traces are of the same size for trs_trace in trs_traces: self.assertEqual(len(trs_trace), sample_count) # Check that all padding is zero for i, trs_trace in enumerate(trs_traces[1:101]): # Difficult case :) if i == 0: continue for si, sample in enumerate(trs_trace[-i:]): self.assertEqual(sample, 0.0 if fmt == SampleCoding.FLOAT else 0, str(i)) # Test that this is indeed not zero self.assertNotEqual(trs_trace[-i - 1], 0)
def test_padding_none(self): sample_count = 1000 with trsfile.open( self.tmp_path, 'w', padding_mode = TracePadding.NONE, headers = { Header.NUMBER_SAMPLES: sample_count, Header.LENGTH_DATA: 8, Header.SAMPLE_CODING: SampleCoding.FLOAT } ) as trs_traces: # This is the length of the trace trs_traces.extend( Trace( SampleCoding.FLOAT, [0] * sample_count, TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(bytes(8))}) ) ) # Length is smaller with self.assertRaises(ValueError): trs_traces.extend( Trace( SampleCoding.FLOAT, [0] * (sample_count - 1), TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(b'\x10' * 8)}) ) ) self.assertEqual(len(trs_traces), 1) # Length is bigger with self.assertRaises(ValueError): trs_traces.extend( Trace( SampleCoding.FLOAT, [0] * (sample_count + 1), TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(b'\x01' * 8)}) ) ) self.assertEqual(len(trs_traces), 1) # Length is equal trs_traces.extend( Trace( SampleCoding.FLOAT, [0] * sample_count, TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(bytes(8))}) ) ) self.assertEqual(len(trs_traces), 2)
def read_parameter_data(self): # Read the trace parameters if Header.TRS_VERSION in self.headers \ and self.headers[Header.TRS_VERSION] > 1 \ and Header.TRACE_PARAMETER_DEFINITIONS in self.headers: definitions = self.headers[Header.TRACE_PARAMETER_DEFINITIONS] data = self.handle.read(definitions.get_total_size()) parameters = TraceParameterMap.deserialize(data, definitions) else: parameters = TraceParameterMap() # Read (legacy) data if Header.LENGTH_DATA in self.headers: data = self.handle.read(self.headers[Header.LENGTH_DATA]) if data: parameters['LEGACY_DATA'] = ByteArrayParameter(data) return parameters
def test_read(self): trace_count = 100 sample_count = 1000 original_traces = [ Trace( SampleCoding.FLOAT, [get_sample(i) for i in range(0, sample_count)], TraceParameterMap() ) for i in range(0, trace_count) ] # Create a trace with trsfile.open(self.tmp_path, 'w', headers = { Header.LABEL_X: 'Testing X', Header.LABEL_Y: 'Testing Y', Header.DESCRIPTION: 'Testing trace creation', }, padding_mode = TracePadding.AUTO ) as trs_traces: trs_traces.extend(original_traces) # Make sure length is equal self.assertEqual(len(original_traces), len(trs_traces)) # Read the trace and check if everything is good with trsfile.open(self.tmp_path, 'r') as trs_traces: # Check if lengths are still good :) self.assertEqual(len(original_traces), len(trs_traces)) # Check if every trace is saved correctly for original_trace, trs_trace in zip(trs_traces, original_traces): self.assertEqual(original_trace, trs_trace)
def test_data(self): self.assertEqual( self.trs_file[0].parameters, TraceParameterMap({ 'LEGACY_DATA': ByteArrayParameter( binascii.unhexlify('43B94E34D3A221B27640C5AD87FBE5DF')) }))
def test_append(self): trace_count = 100 sample_count = 1000 # Append to a non-existing file, behaves same as normal "write" with trsfile.open(self.tmp_path, 'a', padding_mode=TracePadding.AUTO) as trs_traces: self.assertEqual(len(trs_traces), 0) # Extend the trace file with 100 traces with each 1000 samples trs_traces.extend([ Trace( SampleCoding.FLOAT, [0] * sample_count, TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(i.to_bytes(8, byteorder='big'))}) ) for i in range(0, trace_count)] ) self.assertEqual(len(trs_traces), trace_count) # Now open and close for a few times while adding some number of traces expected_length = trace_count for t in range(0, 10): trace_count = (t + 1) * 10 with trsfile.open(self.tmp_path, 'a', padding_mode=TracePadding.AUTO) as trs_traces: self.assertEqual(len(trs_traces), expected_length) # Extend the trace file with 100 traces with each 1000 samples trs_traces.extend([ Trace( SampleCoding.FLOAT, [0] * sample_count, TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(i.to_bytes(8, byteorder='big'))}) ) for i in range(0, trace_count)] ) expected_length += trace_count self.assertEqual(len(trs_traces), expected_length)
def get_traces(self, index): # Try access, and re-raise if wrong for fancy indexing errors try: indices = self.shadow_traces[index] if not isinstance(index, slice): indices = [indices] except IndexError as exception: raise IndexError(exception) # Now obtain all requested traces from file traces = [] for i in indices: # Read the samples path = self.__get_trace_path(i, 'samples') if path.is_file(): with path.open('rb') as tmp_file: # First byte is always sample coding sample_coding = SampleCoding(tmp_file.read(1)[0]) samples = numpy.fromfile(tmp_file, sample_coding.format, -1) else: raise IOError( 'Unable to read samples from trace {0:d}'.format(i)) # Title path = self.__get_trace_path(i, 'title') if path.is_file(): with path.open('rb') as tmp_file: title = tmp_file.read().decode('utf-8') else: title = Header.TRACE_TITLE.default # Read the data path = self.__get_trace_path(i, 'data') if path.is_file(): with path.open('rb') as tmp_file: data = tmp_file.read() else: data = b'' parameters = TraceParameterMap() if data: parameters['LEGACY_DATA'] = ByteArrayParameter(data) # Create trace and make sure headers point to our dict traces.append( Trace(sample_coding, samples, parameters, title, self.headers)) return traces
def test_write_closed(self): trace_count = 100 sample_count = 1000 with trsfile.open(self.tmp_path, 'w', padding_mode=TracePadding.AUTO) as trs_traces: trs_traces.extend([ Trace( SampleCoding.FLOAT, [0] * sample_count, TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(i.to_bytes(8, byteorder='big'))}) ) for i in range(0, trace_count)] ) # Should raise an "ValueError: I/O operation on closed trace set" with self.assertRaises(ValueError): print(trs_traces)
def test_write(self): trace_count = 100 sample_count = 1000 try: with trsfile.open(self.tmp_path, 'w', headers = { Header.LABEL_X: 'Testing X', Header.LABEL_Y: 'Testing Y', Header.DESCRIPTION: 'Testing trace creation', }, padding_mode = TracePadding.AUTO) as trs_traces: trs_traces.extend([ Trace( SampleCoding.FLOAT, [0] * sample_count, TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(i.to_bytes(8, byteorder='big'))}) ) for i in range(0, trace_count)] ) except Exception as e: self.fail('Exception occurred: ' + str(e))
def __init__(self, sample_coding, samples, parameters=TraceParameterMap(), title='trace', headers={}): self.title = title self.parameters = parameters if not type(self.parameters) is TraceParameterMap: raise TypeError( 'Trace parameter data must be supplied as a TraceParameterMap') # Obtain sample coding if not isinstance(sample_coding, SampleCoding): raise TypeError( 'Trace requires sample_coding to be of type \'SampleCoding\'') self.sample_coding = sample_coding # Read in the sample and cast them automatically to the correct type # which is always a numpy.array with a specific dtype as indicated in sample_coding if isinstance(samples, numpy.ndarray): # Check if we need to convert the type of the numpy array if samples.dtype == sample_coding.format: self.samples = samples else: self.samples = samples.astype(sample_coding.format) else: if type(samples) in [bytes, bytearray, str]: self.samples = numpy.frombuffer( samples, dtype=self.sample_coding.format) else: self.samples = numpy.array(samples, dtype=self.sample_coding.format) # Optional headers to add meta support to data slicing (get_input etc) self.headers = headers
def test_exclusive(self): trace_count = 100 sample_count = 1000 # Write to file exclusively with trsfile.open(self.tmp_path, 'x', padding_mode=TracePadding.AUTO) as trs_traces: self.assertEqual(len(trs_traces), 0) # Extend the trace file with 100 traces with each 1000 samples trs_traces.extend([ Trace( SampleCoding.FLOAT, [0] * sample_count, TraceParameterMap({'LEGACY_DATA': ByteArrayParameter(i.to_bytes(8, byteorder='big'))}) ) for i in range(0, trace_count)] ) self.assertEqual(len(trs_traces), trace_count) # Now try again (this should throw an exception) with self.assertRaises(FileExistsError): with trsfile.open(self.tmp_path, 'x') as trs_traces: self.assertEqual(len(trs_traces), trace_count)
def test_deserialize(self): self.assertDictEqual( TraceParameterMap.deserialize( self.SERIALIZED_MAP, TestTraceParameterDefinitionMap.create_parameterdefinitionmap( )), self.create_parametermap())
def create_parametermap() -> TraceParameterMap: map = TraceParameterMap() map['INPUT'] = ByteArrayParameter(list(TestTraceParameterMap.CAFEBABE)) map['TITLE'] = StringParameter('Hello, world!') map['中文'] = StringParameter('你好,世界') return map