diff --git a/hw_diag/tests/test_get_serial_number.py b/hw_diag/tests/test_get_serial_number.py index 03f24b93..5a85cda8 100644 --- a/hw_diag/tests/test_get_serial_number.py +++ b/hw_diag/tests/test_get_serial_number.py @@ -3,9 +3,17 @@ from unittest.mock import mock_open, patch from hw_diag.utilities.hardware import get_serial_number, load_serial_number, \ - load_cpu_info + load_cpu_info, has_valid_serial TEST_SERIAL = "00000000a3e7kg80" +TEST_SERIAL_ALL_ZERO = "000000000000000000000000000000" +TEST_SERIAL_ROCKPI = "d18dbe5c2a58cc61" +TEST_SERIAL_BOBCAT = "ba033cbdca6d626f" +TEST_SERIAL_RASPI = "000000009e3cb787" +TEST_SERIAL_ROCKPI_WRONG = "W1EP3DN9PU" +TEST_SERIAL_BOBCAT_WRONG = "c3d9b8674f4b94f6" +TEST_SERIAL_SHORT = "123ABC" +TEST_SERIAL_EMPTY = "" TEST_CPU_INFO = """ processor : 0 @@ -22,6 +30,14 @@ TEST_SERIAL_NUMBER_RESULT = {'serial': '00000000a3e7kg80'} TEST_CPU_INFO_RESULT = {'serial': '912558f1a3ae877d'} +SERIAL_VALID = {'serial': '912558f1a3ae877dabcdef1234567890ABCDEF'} +SERIAL_ALL_ZERO = {'serial': '000000000000000'} +SERIAL_WRONG_ROCKPI = {'serial': 'W1EP3DN9PU'} +SERIAL_WRONG_BOBCAT = {'serial': 'c3d9b8674f4b94f6'} +SERIAL_NON_HEX_TEN_DIGITS = {'serial': 'XXXYYYZZZZ'} +SERIAL_SHORT = {'serial': 'ABC123abc'} +SERIAL_BLANK = {'serial': ''} +SERIAL_MISSING = {} FAILED_CPU_INFO_RESULT = {} FAILED_SERIAL_NUMBER_RESULT = {} @@ -89,3 +105,157 @@ def test_load_cpuinfo_fail(self): captured = self.caplog self.assertTrue('failed to load /proc/cpuinfo' in str(captured.text)) self.assertEqual(cpuinfo, FAILED_CPU_INFO_RESULT) + + def test_has_valid_serial_all_zeros(self): + self.assertFalse(has_valid_serial(SERIAL_ALL_ZERO)) + + def test_has_valid_serial_non_hex(self): + self.assertFalse(has_valid_serial(SERIAL_NON_HEX_TEN_DIGITS)) + + def test_has_valid_serial_knonwn_wrong(self): + self.assertFalse(has_valid_serial(SERIAL_WRONG_ROCKPI)) + + def test_has_valid_serial_knonwn_wrong(self): + self.assertFalse(has_valid_serial(SERIAL_WRONG_BOBCAT)) + + def test_has_valid_serial_mising(self): + self.assertFalse(has_valid_serial(SERIAL_MISSING)) + + def test_has_valid_serial_blank(self): + self.assertFalse(has_valid_serial(SERIAL_BLANK)) + + def test_has_valid_serial_short(self): + self.assertFalse(has_valid_serial(SERIAL_SHORT)) + + def test_has_valid_serial_true(self): + self.assertTrue(has_valid_serial(SERIAL_VALID)) + + @patch('hw_diag.utilities.hardware.is_rockpi') + @patch('hw_diag.utilities.hardware.load_cpu_info') + @patch('hw_diag.utilities.hardware.load_serial_number') + def test_get_serial_number_rockpi(self, mock_serial, mock_cpuinfo, mock_rockpi): + mock_rockpi.return_value = True + mock_cpuinfo.return_value = {'serial': TEST_SERIAL_ROCKPI} + mock_serial.return_value = {'serial': TEST_SERIAL_ROCKPI_WRONG} + + right_value = {'serial_number': 'd18dbe5c2a58cc61'} + get_serial_number(self.diag) + self.assertEqual(self.diag["serial_number"], + right_value["serial_number"]) + + @patch('hw_diag.utilities.hardware.is_rockpi') + @patch('hw_diag.utilities.hardware.load_cpu_info') + @patch('hw_diag.utilities.hardware.load_serial_number') + def test_get_serial_number_all_zero(self, mock_serial, mock_cpuinfo, mock_rockpi): + mock_rockpi.return_value = True + mock_cpuinfo.return_value = {'serial': TEST_SERIAL_ALL_ZERO} + mock_serial.return_value = {'serial': TEST_SERIAL_ALL_ZERO} + + right_value = {'serial_number': 'Serial number not found'} + get_serial_number(self.diag) + self.assertEqual(self.diag["serial_number"], + right_value["serial_number"]) + + @patch('hw_diag.utilities.hardware.is_rockpi') + @patch('hw_diag.utilities.hardware.load_cpu_info') + @patch('hw_diag.utilities.hardware.load_serial_number') + def test_get_serial_number_rockpi_raspi(self, mock_serial, mock_cpuinfo, mock_rockpi): + mock_rockpi.return_value = True + mock_cpuinfo.return_value = {'serial': TEST_SERIAL_ROCKPI} + mock_serial.return_value = {'serial': TEST_SERIAL} + + right_value = {'serial_number': 'd18dbe5c2a58cc61'} + get_serial_number(self.diag) + self.assertEqual(self.diag["serial_number"], + right_value["serial_number"]) + + @patch('hw_diag.utilities.hardware.is_rockpi') + @patch('hw_diag.utilities.hardware.load_cpu_info') + @patch('hw_diag.utilities.hardware.load_serial_number') + def test_get_serial_number_short_wrong(self, mock_serial, mock_cpuinfo, mock_rockpi): + mock_rockpi.return_value = False + mock_cpuinfo.return_value = {'serial': TEST_SERIAL_SHORT} + mock_serial.return_value = {'serial': TEST_SERIAL_BOBCAT_WRONG} + + right_value = {'serial_number': 'Serial number not found'} + get_serial_number(self.diag) + self.assertEqual(self.diag["serial_number"], + right_value["serial_number"]) + + @patch('hw_diag.utilities.hardware.is_rockpi') + @patch('hw_diag.utilities.hardware.load_cpu_info') + @patch('hw_diag.utilities.hardware.load_serial_number') + def test_get_serial_number_raspi_rockpi(self, mock_serial, mock_cpuinfo, mock_rockpi): + mock_rockpi.return_value = False + mock_cpuinfo.return_value = {'serial': TEST_SERIAL_ROCKPI} + mock_serial.return_value = {'serial': TEST_SERIAL} + + right_value = {'serial_number': '00000000a3e7kg80'} + get_serial_number(self.diag) + self.assertEqual(self.diag["serial_number"], + right_value["serial_number"]) + + @patch('hw_diag.utilities.hardware.is_rockpi') + @patch('hw_diag.utilities.hardware.load_cpu_info') + @patch('hw_diag.utilities.hardware.load_serial_number') + def test_get_serial_number_raspi(self, mock_serial, mock_cpuinfo, mock_rockpi): + mock_rockpi.return_value = False + mock_cpuinfo.return_value = {'serial': TEST_SERIAL} + mock_serial.return_value = {'serial': TEST_SERIAL} + + right_value = {'serial_number': '00000000a3e7kg80'} + get_serial_number(self.diag) + self.assertEqual(self.diag["serial_number"], + right_value["serial_number"]) + + @patch('hw_diag.utilities.hardware.is_rockpi') + @patch('hw_diag.utilities.hardware.load_cpu_info') + @patch('hw_diag.utilities.hardware.load_serial_number') + def test_get_serial_number_bobcat(self, mock_serial, mock_cpuinfo, mock_rockpi): + mock_rockpi.return_value = False + mock_cpuinfo.return_value = {'serial': TEST_SERIAL_BOBCAT} + mock_serial.return_value = {'serial': TEST_SERIAL_BOBCAT_WRONG} + + right_value = {'serial_number': 'ba033cbdca6d626f'} + get_serial_number(self.diag) + self.assertEqual(self.diag["serial_number"], + right_value["serial_number"]) + + @patch('hw_diag.utilities.hardware.is_rockpi') + @patch('hw_diag.utilities.hardware.load_cpu_info') + @patch('hw_diag.utilities.hardware.load_serial_number') + def test_get_serial_number_rockpi_zero(self, mock_serial, mock_cpuinfo, mock_rockpi): + mock_rockpi.return_value = True + mock_cpuinfo.return_value = {'serial': TEST_SERIAL_ALL_ZERO} + mock_serial.return_value = {'serial': TEST_SERIAL_ROCKPI} + + right_value = {'serial_number': 'd18dbe5c2a58cc61'} + get_serial_number(self.diag) + self.assertEqual(self.diag["serial_number"], + right_value["serial_number"]) + + @patch('hw_diag.utilities.hardware.is_rockpi') + @patch('hw_diag.utilities.hardware.load_cpu_info') + @patch('hw_diag.utilities.hardware.load_serial_number') + def test_get_serial_number_rockpi_backwards(self, mock_serial, mock_cpuinfo, mock_rockpi): + mock_rockpi.return_value = True + mock_cpuinfo.return_value = {'serial': TEST_SERIAL} + mock_serial.return_value = {'serial': TEST_SERIAL_ROCKPI} + + right_value = {'serial_number': '00000000a3e7kg80'} + get_serial_number(self.diag) + self.assertEqual(self.diag["serial_number"], + right_value["serial_number"]) + + @patch('hw_diag.utilities.hardware.is_rockpi') + @patch('hw_diag.utilities.hardware.load_cpu_info') + @patch('hw_diag.utilities.hardware.load_serial_number') + def test_get_serial_number_raspi_empty(self, mock_serial, mock_cpuinfo, mock_rockpi): + mock_rockpi.return_value = False + mock_cpuinfo.return_value = {'serial': TEST_SERIAL} + mock_serial.return_value = {'serial': TEST_SERIAL_EMPTY} + + right_value = {'serial_number': '00000000a3e7kg80'} + get_serial_number(self.diag) + self.assertEqual(self.diag["serial_number"], + right_value["serial_number"]) diff --git a/hw_diag/utilities/hardware.py b/hw_diag/utilities/hardware.py index bb696251..62664c9a 100644 --- a/hw_diag/utilities/hardware.py +++ b/hw_diag/utilities/hardware.py @@ -1,6 +1,7 @@ import dbus import os import psutil +import string from typing import Union from urllib.parse import urlparse from hm_pyhelper.logger import get_logger @@ -78,6 +79,20 @@ DTPARAM_CONFIG_VAR_NAMES = ['BALENA_HOST_CONFIG_dtparam', 'RESIN_HOST_CONFIG_dtparam'] EXT_ANT_DTPARAM = '"ant2"' +INCORRECT_BOBCAT_SERIALS = ['c3d9b8674f4b94f6'] +INCORRECT_ROCKPI_SERIALS = [ + 'W1EP3DN9PU', + '0UQMAKIBII', + 'PN06893W5V', + 'KLOFHWLY95', + '3IT1I4E9TG', + 'CKHZ4CHI1P', + 'I4YE1UGF5N', + 'PERTSKMCT0', + 'S63QCF54CJ', + 'YYMSYLJWG8' +] + def should_display_lte(diagnostics): variant = diagnostics.get('VA') @@ -275,11 +290,31 @@ def has_valid_serial(cpuinfo: dict) -> bool: if CPUINFO_SERIAL_KEY not in cpuinfo: return False - # Check if serial number is all 0s... serial_number = cpuinfo[CPUINFO_SERIAL_KEY] + + # Check if serial number is all 0s... if all(c in '0' for c in str(serial_number)): return False + # Check if serial number is a known incorrect ROCKPi serial + # in INCORRECT_ROCKPI_SERIALS... + if str(serial_number) in INCORRECT_ROCKPI_SERIALS: + return False + + # Check if serial number is a known incorrect Bobcat serial + # in INCORRECT_BOBCAT_SERIALS... + if str(serial_number) in INCORRECT_BOBCAT_SERIALS: + return False + + # Check if serial number is 10 characters and non-hexadecimal... + if len(str(serial_number)) == 10 and not all( + c in string.hexdigits for c in str(serial_number)): + return False + + # Check if serial number is < 10 characters... + if len(str(serial_number)) < 10: + return False + return True