Unit tests¶
Tests for driver implementation¶
Tests for IM871-A driver. Uses mocked tests when not on Gateway. On Gateway, tests run using hardware peripheral.
Future dev.:
Try spec=True to investigate if MagicMock can correctly spec the patched classes and functions.
E.g. when patching serial.Serial, the MagicMock should appear to have all relevant methods.
This could eliminate some need for spec’ing our own test doubles (fakes).
-
class
test.test_DriverClass.PatchSerial(read_raw_return)[source]¶ Fakes the serial.Serial object. Avoids attempts of write/read operations from /dev/tty devices on local machines.
-
class
test.test_DriverClass.PipeWriter[source]¶ Fakes the builtin method used to open a pipe and write to it. This avoids pipes being opened on local machines.
-
test.test_DriverClass.input_data()[source]¶ Fixture that returns raw usb data, processed data and processed data with errors
-
test.test_DriverClass.patched_driver(mock_obj_im871a_port, mock_obj_fifo, mock_obj_serial_conn, mock_open)[source]¶ Make a driver fixture where we’ve patched (bypass/override) the port.Serial dependency with our own fake object. The port.Serial-function (serial.Serial) is used when the driver tries to establish serial connection. Patch os.mkfifo to prevent making FIFO (pipe) in the local OS during object construction. Set up that we test on one specific test vector.
-
test.test_DriverClass.test_CRC_check_fails_RPi(IM871A_pipe, input_data)[source]¶ Tests if a unsuccesfull CRC-check returns false
-
test.test_DriverClass.test_CRC_check_succes_RPi(IM871A_pipe, input_data)[source]¶ Tests if a succesfull CRC-check returns true
-
test.test_DriverClass.test_constructor_destructor(patched_driver)[source]¶ Test construction and destruction of a driver object is OK.
-
test.test_DriverClass.test_linkmodes_RPi(IM871A_pipe)[source]¶ Testing all the linkmodes possible with IM871A
-
test.test_DriverClass.test_object_instatiated_true_RPi(IM871A_pipe)[source]¶ Testing if an object of the type IM871A can be instantiated
-
test.test_DriverClass.test_read_data(patched_driver)[source]¶ Already Patch out the pipe dependency to an instance of local PipeWriter-type object that we can easily read.
-
test.test_DriverClass.test_read_data_RPi(IM871A_pipe, input_data)[source]¶ Testing if it’s possible to read from the pipe
Tests for OmniPower implementation¶
Tests for the functionality of OmniPower implementation.
-
test.test_OmniPower.bad_telegrams_list()[source]¶ Sets up a list of bad telegrams that must cause exceptions at various places.
-
test.test_OmniPower.omnipower_setup(omnipower_base)[source]¶ Sets up an omnipower test fixture with at least one telegram stored in log.
-
test.test_OmniPower.omnipower_with_no_aes_key(omnipower_base)[source]¶ Creates a good OmniPower object with empty AES key.
-
test.test_OmniPower.test_Omnipower_longtelegram(omnipower_base)[source]¶ Assure Omnipower class can process long telegrams
-
test.test_OmniPower.test_Omnipower_noAESkey(omnipower_base)[source]¶ Assure that Omnipower class can’t decrypt with wrong or no AES-key
-
test.test_OmniPower.test_Omnipower_notmytelegram(omnipower_base)[source]¶ Assure Omnipower class rejects a telegram from an unknown sensor
-
test.test_OmniPower.test_Omnipower_shorttelegram(omnipower_base)[source]¶ Assure Omnipower class can process long telegrams
-
test.test_OmniPower.test_c1telegram_must_raise_exception(bad_telegrams_list)[source]¶ Test that C1 Telegram initialized with bad bytestream raises exception.
-
test.test_OmniPower.test_decrypt_must_raise_aes_key_error(omnipower_with_no_aes_key, good_telegrams_list)[source]¶ If AES key is not OK, decrypt must raise an AesKeyException.
-
test.test_OmniPower.test_decrypt_must_raise_crc_check_error(omnipower_base, bad_payload_list)[source]¶ If the payload has been modified or mangled, CRC16 check must fail, and a CrcCheckException is raised, which passes through .decrypt().
-
test.test_OmniPower.test_decrypt_using_must_return_false_for_bad_key(omnipower_with_no_aes_key, good_telegrams_list)[source]¶ Decrypt_using is the telegram that attempts to decrypt itself using a meter object. If the AES key in the meter object is bad, it cannot be used for decryption. Then decrypt_using must return False to signify failed operation. Test strategy: Good telegram + bad AES key -> AesKeyException.
-
test.test_OmniPower.test_decrypt_using_must_return_false_for_bad_payload(omnipower_base, bad_payload_list)[source]¶ Decrypt_using is the telegram that attempts to decrypt itself using a meter object. If the payload is bad, the meter object cannot successfully validate CRC16. Then decrypt_using must return False to signify failed operation. Test strategy: Bad payload + good AES key -> CrcCheckException.
-
test.test_OmniPower.test_extract_measurement_frame_returns_empty_if_tlg_not_decrypted(omnipower_base, good_telegrams_list)[source]¶ Expect OmniPower’s extract_measurement_frame to return an empty object if the telegram has not been decrypted, so there is no data to extract. Per spec., it must then return an empty object. Test strategy, used the implemented method .is_empty() to test this.
-
test.test_OmniPower.test_json_full_log(omnipower_setup)[source]¶ Test that a full log of MeterMeasurement objects dumped to JSON can all be recovered correctly.
-
test.test_OmniPower.test_process_telegram_returns_false_if_not_parsable(omnipower_base, good_telegrams_list)[source]¶ Expect OmniPower’s process_telegram to return False if the telegram cannot be parsed / handled by OmniPower. Reasons:
Not sent from this meter
decrypt_using returns false (tested above)
empty frame returned (tested above)
add_measurement_to_log fails (not tested)
Tests for MeterMeasurement implementation¶
Tests for the functionality of MeterMeasurement implementation.
-
test.test_MeterMeasure.initialized_measurement_frame()[source]¶ Sets up a measurement frame with ID and fixed Zulu timestamp, but no data.
-
test.test_MeterMeasure.omnipower_setup()[source]¶ Sets up an omnipower test fixture with at least one telegram stored in log.
-
test.test_MeterMeasure.test_add_measurement(MeasureFix, keys)[source]¶ Test the “add_measurement”-method from MeterMeasurement
-
test.test_MeterMeasure.test_as_dict(MeasureFix, keys)[source]¶ Test the “as_dict” method from MeterMeasurement