def test_read_multiple_banks(self): """ Test read from multiple banks. """ def read(_data): """ Read dummy. """ if _data["bank"] == 1: return {"data": "abc" + "\xff" * 200 + "def" + "\xff" * 48} if _data["bank"] == 100: return { "data": "hello" + "\x00" * 100 + "world" + "\x00" * 146 } else: raise Exception("Wrong page") eeprom_file = EepromFile(MasterCommunicator(read)) address1 = EepromAddress(1, 2, 10) address2 = EepromAddress(100, 4, 10) address3 = EepromAddress(100, 105, 5) data = eeprom_file.read([address1, address2, address3]) self.assertEquals(3, len(data)) self.assertEquals(address1, data[address1].address) self.assertEquals("c" + "\xff" * 9, data[address1].bytes) self.assertEquals(address2, data[address2].address) self.assertEquals("o" + "\x00" * 9, data[address2].bytes) self.assertEquals(address3, data[address3].address) self.assertEquals("world", data[address3].bytes)
def get_module_addresses(module_type): """ Get the addresses for the modules of the given type. :param module_type: the type of the module (O, R, D, I, T, C) :param module_type: chr :returns: A list containing the addresses of the modules (strings of length 4). """ eeprom_file = EepromFile() base_address = EepromAddress(0, 1, 2) no_modules = eeprom_file.read([base_address]) modules = [] no_input_modules = ord(no_modules[base_address].bytes[0]) for i in range(no_input_modules): address = EepromAddress(2 + i, 252, 1) is_can = eeprom_file.read([address])[address].bytes == 'C' address = EepromAddress(2 + i, 0, 4) module = eeprom_file.read([address])[address].bytes if not is_can or module[0] == 'C': modules.append(module) no_output_modules = ord(no_modules[base_address].bytes[1]) for i in range(no_output_modules): address = EepromAddress(33 + i, 0, 4) modules.append(eeprom_file.read([address])[address].bytes) return [module for module in modules if module[0] == module_type]
def test_cache_invalidate(self): """ Test the cache invalidation. """ state = {'count': 0} def read(_): """ Read dummy. """ if state['count'] == 0: state['count'] = 1 return {"data": "\xff" * 256} elif state['count'] == 1: state['count'] = 2 return {"data": "\xff" * 256} else: raise Exception("Too many reads !") communicator = MasterCommunicator(read, None) eeprom_file = EepromFile(communicator) address = EepromAddress(1, 0, 256) read = eeprom_file.read([address]) self.assertEquals("\xff" * 256, read[address].bytes) # Second read should come from cache. address = EepromAddress(1, 0, 256) read = eeprom_file.read([address]) self.assertEquals("\xff" * 256, read[address].bytes) eeprom_file.invalidate_cache() # Should be read from communicator, since cache is invalid address = EepromAddress(1, 0, 256) read = eeprom_file.read([address]) self.assertEquals("\xff" * 256, read[address].bytes) self.assertEquals(2, state['count'])
def get_module_addresses(master_communicator, type): """ Get the addresses for the modules of the given type. :param master_communicator: used to read the addresses from the master eeprom. :type master_communicator: MasterCommunicator :param type: the type of the module (o, r, d, i, t, c) :param type: chr :returns: A list containing the addresses of the modules (strings of length 4). """ eeprom_file = EepromFile(master_communicator) base_address = EepromAddress(0, 1, 2) no_modules = eeprom_file.read([base_address]) modules = [] no_input_modules = ord(no_modules[base_address].bytes[0]) for i in range(no_input_modules): address = EepromAddress(2 + i, 0, 4) modules.append(eeprom_file.read([address])[address].bytes) no_output_modules = ord(no_modules[base_address].bytes[1]) for i in range(no_output_modules): address = EepromAddress(33 + i, 0, 4) modules.append(eeprom_file.read([address])[address].bytes) return [module for module in modules if module[0].lower() == type]
def test_from_data_dict(self): """ Test from_data_dict. """ cdt = CompositeDataType([('one', EepromByte((1, 2))), ('two', EepromByte((1, 3)))]) addr1 = EepromAddress(1, 2, 1) addr2 = EepromAddress(1, 3, 1) data_dict = {addr1 : EepromData(addr1, str(chr(12))), addr2 : EepromData(addr2, str(chr(34)))} self.assertEquals([12, 34], cdt.from_data_dict(data_dict))
def test_from_eeprom_wrong_data(self): """ Test from_eeprom_data with wrong data. """ try: model3_data = [EepromData(EepromAddress(3, 4, 10), "hello worljkfdsjklsadfjklsadf"), EepromData(EepromAddress(3, 14, 1), str(chr(123))), EepromData(EepromAddress(3, 15, 2), str(chr(1) + chr(200)))] Model3.from_eeprom_data(model3_data) self.fail("Should have receive TypeError.") except TypeError as type_error: self.assertTrue("Length" in str(type_error))
def test_to_eeprom_data(self): """ Test to_eeprom_data. """ cdt = CompositeDataType([('one', EepromByte((1, 2))), ('two', EepromByte((1, 3)))]) data = cdt.to_eeprom_data([34, 12]) self.assertEquals(2, len(data)) self.assertEquals(EepromAddress(1, 2, 1), data[0].address) self.assertEquals(str(chr(34)), data[0].bytes) self.assertEquals(EepromAddress(1, 3, 1), data[1].address) self.assertEquals(str(chr(12)), data[1].bytes)
def test_from_eeprom_data(self): """ Test from_eeprom_data. """ model1_data = [EepromData(EepromAddress(1, 3, 100), "test" + "\xff" * 96)] model1 = Model1.from_eeprom_data(model1_data, 1) self.assertEquals(1, model1['id']) self.assertEquals("test", model1['name']) model2_data = [EepromData(EepromAddress(3, 4, 100), "hello world" + "\xff" * 89)] model2 = Model2.from_eeprom_data(model2_data) self.assertEquals("hello world", model2['name']) model3_data = [EepromData(EepromAddress(3, 4, 10), "hello worl"), EepromData(EepromAddress(3, 14, 1), str(chr(123))), EepromData(EepromAddress(3, 15, 2), str(chr(200) + chr(1)))] model3 = Model3.from_eeprom_data(model3_data) self.assertEquals("hello worl", model3['name']) self.assertEquals(123, model3['link']) self.assertEquals(456, model3['out']) model6_data = [EepromData(EepromAddress(3, 4, 10), "test" + "\xff" * 6), EepromData(EepromAddress(3, 14, 1), str(chr(1))), EepromData(EepromAddress(3, 15, 2), str(chr(2) + chr(0)))] model6 = Model6.from_eeprom_data(model6_data) self.assertEquals("test", model6['name']) self.assertEquals([1, 2], model6['status'])
def test_write_multiple_fields(self): """ Test writing multiple fields to the eeprom file. """ done = {} def read(data): """ Read dummy. """ if data["bank"] == 1: done['read1'] = True return {"data": "\xff" * 256} elif data["bank"] == 2: done['read2'] = True return {"data": "\x00" * 256} else: raise Exception("Wrong page") def write(data): """ Write dummy. """ if 'write1' not in done: done['write1'] = True self.assertEquals(1, data["bank"]) self.assertEquals(2, data["address"]) self.assertEquals("abc", data["data"]) elif 'write2' not in done: done['write2'] = True self.assertEquals(2, data["bank"]) self.assertEquals(123, data["address"]) self.assertEquals("More bytes", data["data"]) elif 'write3' not in done: done['write3'] = True self.assertEquals(2, data["bank"]) self.assertEquals(133, data["address"]) self.assertEquals(" than 10", data["data"]) else: raise Exception("Too many writes") communicator = MasterCommunicator(read, write) eeprom_file = EepromFile(communicator) eeprom_file.write([ EepromData(EepromAddress(1, 2, 3), "abc"), EepromData(EepromAddress(2, 123, 18), "More bytes than 10") ]) self.assertTrue('read1' in done) self.assertTrue('read2' in done) self.assertTrue('write1' in done) self.assertTrue('write2' in done) self.assertTrue('write3' in done)
def test_write_single_field(self): """ Write a single field to the eeprom file. """ done = {} def read(data): """ Read dummy. """ if data["bank"] == 1: done['read1'] = True return {"data": "\xff" * 256} else: raise Exception("Wrong page") def write(data): """ Write dummy. """ self.assertEquals(1, data["bank"]) self.assertEquals(2, data["address"]) self.assertEquals("abc", data["data"]) done['write'] = True communicator = MasterCommunicator(read, write) eeprom_file = EepromFile(communicator) eeprom_file.write([EepromData(EepromAddress(1, 2, 3), "abc")]) self.assertTrue('read1' in done) self.assertTrue('write' in done)
def test_from_eeprom_wrong_address(self): """ Test from_eeprom_data with wrong address. """ try: model1_data = [EepromData(EepromAddress(3, 4, 100), "test" + "\xff" * 96)] Model1.from_eeprom_data(model1_data, 1) self.fail("Should have receive KeyError.") except KeyError as key_error: self.assertTrue("(B1 A3 L100)" in str(key_error))
def test_cache_write(self): """ Test the eeprom cache on writing. """ state = {'read': 0, 'write': 0} def read(_): """ Read dummy. """ if state['read'] == 0: state['read'] = 1 return {"data": "\xff" * 256} else: raise Exception("Too many reads !") def write(data): """ Write dummy. """ if state['write'] == 0: self.assertEquals(1, data["bank"]) self.assertEquals(100, data["address"]) self.assertEquals("\x00" * 10, data["data"]) state['write'] = 1 elif state['write'] == 1: self.assertEquals(1, data["bank"]) self.assertEquals(110, data["address"]) self.assertEquals("\x00" * 10, data["data"]) state['write'] = 2 else: raise Exception("Too many writes !") communicator = MasterCommunicator(read, write) eeprom_file = EepromFile(communicator) address = EepromAddress(1, 0, 256) read = eeprom_file.read([address]) self.assertEquals("\xff" * 256, read[address].bytes) eeprom_file.write([EepromData(EepromAddress(1, 100, 20), "\x00" * 20)]) address = EepromAddress(1, 0, 256) read = eeprom_file.read([address]) self.assertEquals("\xff" * 100 + "\x00" * 20 + "\xff" * 136, read[address].bytes) self.assertEquals(1, state['read']) self.assertEquals(2, state['write'])
def test_cache_write_exception(self): """ The cache should be invalidated if a write fails. """ state = {'read': 0, 'write': 0} def read(_): """ Read dummy. """ if state['read'] == 0: state['read'] = 1 return {"data": "\xff" * 256} elif state['read'] == 1: state['read'] = 2 return {"data": "\xff" * 256} else: raise Exception("Too many reads !") def write(_): """ Write dummy. """ state['write'] += 1 raise Exception("write fails...") communicator = MasterCommunicator(read, write) eeprom_file = EepromFile(communicator) address = EepromAddress(1, 0, 256) read = eeprom_file.read([address]) self.assertEquals("\xff" * 256, read[address].bytes) try: eeprom_file.write( [EepromData(EepromAddress(1, 100, 20), "\x00" * 20)]) self.fail("Should not get here !") except Exception: pass address = EepromAddress(1, 0, 256) read = eeprom_file.read([address]) self.assertEquals("\xff" * 256, read[address].bytes) self.assertEquals(2, state['read']) self.assertEquals(1, state['write'])
def test_cache(self): """ Test the caching of banks. """ state = { 'count' : 0 } def read(data): """ Read dummy. """ if state['count'] == 0: state['count'] = 1 return {"data" : "\xff" * 256} else: raise Exception("Too many reads !") communicator = MasterCommunicatorDummy(read, None) eeprom_file = EepromFile(communicator) read = eeprom_file.read([EepromAddress(1, 0, 256)]) self.assertEquals("\xff" * 256, read[0].bytes) # Second read should come from cache, if read is called # an exception will be thrown. read = eeprom_file.read([EepromAddress(1, 0, 256)]) self.assertEquals("\xff" * 256, read[0].bytes)
def test_read_one_bank_two_addresses(self): """ Test read from one bank with two addresses. """ def read(_data): """ Read dummy """ if _data["bank"] == 1: return {"data": "abc" + "\xff" * 200 + "def" + "\xff" * 48} else: raise Exception("Wrong page") eeprom_file = EepromFile(MasterCommunicator(read)) address1 = EepromAddress(1, 2, 10) address2 = EepromAddress(1, 203, 4) data = eeprom_file.read([address1, address2]) self.assertEquals(2, len(data)) self.assertEquals(address1, data[address1].address) self.assertEquals("c" + "\xff" * 9, data[address1].bytes) self.assertEquals(address2, data[address2].address) self.assertEquals("def\xff", data[address2].bytes)
def test_write_multiple_fields_same_batch(self): """ Test writing multiple fields to the eeprom file. """ done = {} def read(data): """ Read dummy. """ if data["bank"] == 1: done['read'] = True return {"data": "\xff" * 256} else: raise Exception("Wrong page") def write(data): """ Write dummy. """ if 'write1' not in done: done['write1'] = True self.assertEquals(1, data["bank"]) self.assertEquals(2, data["address"]) self.assertEquals("abc\xff\xff\xffdefg", data["data"]) elif 'write2' not in done: done['write2'] = True self.assertEquals(1, data["bank"]) self.assertEquals(12, data["address"]) self.assertEquals("hijklmn", data["data"]) else: raise Exception("Too many writes") communicator = MasterCommunicator(read, write) eeprom_file = EepromFile(communicator) eeprom_file.write([ EepromData(EepromAddress(1, 2, 3), "abc"), EepromData(EepromAddress(1, 8, 11), "defghijklmn") ]) self.assertTrue('read' in done) self.assertTrue('write1' in done) self.assertTrue('write2' in done)
def test_cache(self): """ Test the caching of banks. """ state = {'count': 0} def read(_): """ Read dummy. """ if state['count'] == 0: state['count'] = 1 return {"data": "\xff" * 256} else: raise Exception("Too many reads !") SetUpTestInjections(master_communicator=MasterCommunicator(read)) eeprom_file = EepromFile() address = EepromAddress(1, 0, 256) read = eeprom_file.read([address]) self.assertEquals("\xff" * 256, read[address].bytes) # Second read should come from cache, if read is called # an exception will be thrown. address = EepromAddress(1, 0, 256) read = eeprom_file.read([address]) self.assertEquals("\xff" * 256, read[address].bytes)
def test_read_one_bank_one_address(self): """ Test read from one bank with one address """ def read(_data): """ Read dummy. """ if _data["bank"] == 1: return {"data": "abc" + "\xff" * 200 + "def" + "\xff" * 48} else: raise Exception("Wrong page") eeprom_file = EepromFile(MasterCommunicator(read)) address = EepromAddress(1, 0, 3) data = eeprom_file.read([address]) self.assertEquals(1, len(data)) self.assertEquals(address, data[address].address) self.assertEquals("abc", data[address].bytes)
def test_write_end_of_page(self): """ Test writing an address that is close (< BATCH_SIZE) to the end of the page. """ done = {} def read(_): """ Read dummy. """ return {"data": "\x00" * 256} def write(data): """ Write dummy. """ self.assertEquals(117, data["bank"]) self.assertEquals(248, data["address"]) self.assertEquals("test\xff\xff\xff\xff", data["data"]) done['done'] = True SetUpTestInjections(master_communicator=MasterCommunicator(read, write)) eeprom_file = EepromFile() eeprom_file.write([EepromData(EepromAddress(117, 248, 8), "test\xff\xff\xff\xff")]) self.assertTrue(done['done'])
class Model4(EepromModel): """ Dummy model with a dynamic maximum id. """ id = EepromId(10, address=EepromAddress(0, 0, 1), multiplier=2) name = EepromString(10, lambda id: (1, 2 + id * 10))