Use importlib.util to replace imp

Since the imp module is deprecated and scheduled for removal in
Python 3.12 in favor of importlib, update the relevant libraries to
resolve any ModuleNotFoundError issues with Python 3.12.

Changes:
- use import importlib.util instead of import imp

Tested:
- Ran basic test pass with Python 3.10 and 3.12.

Change-Id: I25dde939dd25268b2ae329b0121858bec20ed03c
Signed-off-by: Brian Ma <chma0@nuvoton.com>
diff --git a/data/model.py b/data/model.py
index 78a7284..adeec17 100755
--- a/data/model.py
+++ b/data/model.py
@@ -1,12 +1,19 @@
 #!/usr/bin/env python3 -u
-import imp as imp
+import importlib.util
 import string as string
 
 from robot.libraries.BuiltIn import BuiltIn
 
 
+def load_source(name, module_path):
+    spec = importlib.util.spec_from_file_location(name, module_path)
+    module = importlib.util.module_from_spec(spec)
+    spec.loader.exec_module(module)
+    return module
+
+
 def get_sensor(module_name, value):
-    m = imp.load_source("module.name", module_name)
+    m = load_source("module.name", module_name)
 
     for i in m.ID_LOOKUP["SENSOR"]:
         if m.ID_LOOKUP["SENSOR"][i] == value:
@@ -16,7 +23,7 @@
 
 
 def get_inventory_sensor(module_name, value):
-    m = imp.load_source("module.name", module_name)
+    m = load_source("module.name", module_name)
 
     value = string.replace(value, m.INVENTORY_ROOT, "<inventory_root>")
 
@@ -29,7 +36,7 @@
 
 def get_inventory_list(module_name):
     inventory_list = []
-    m = imp.load_source("module.name", module_name)
+    m = load_source("module.name", module_name)
 
     for i in m.ID_LOOKUP["FRU"]:
         s = m.ID_LOOKUP["FRU"][i]
@@ -41,7 +48,7 @@
 
 def get_inventory_fru_type_list(module_name, fru_type):
     inventory_list = []
-    m = imp.load_source("module.name", module_name)
+    m = load_source("module.name", module_name)
 
     for i in m.FRU_INSTANCES.keys():
         if m.FRU_INSTANCES[i]["fru_type"] == fru_type:
@@ -57,7 +64,7 @@
 
 def get_FRU_component_name_list(module_name):
     name_list = []
-    m = imp.load_source("module.name", module_name)
+    m = load_source("module.name", module_name)
 
     for name in m.FRU_COMPONENT_NAME:
         name_list.append(name)
@@ -67,7 +74,7 @@
 
 
 def get_ipmi_rest_fru_field_map(module_name):
-    m = imp.load_source("module.name", module_name)
+    m = load_source("module.name", module_name)
 
     ipmi_rest_fru_field_map = dict.copy(m.ipmi_rest_fru_field_map)
 
diff --git a/data/platform_variables.py b/data/platform_variables.py
index 512b8ea..84ac259 100644
--- a/data/platform_variables.py
+++ b/data/platform_variables.py
@@ -4,7 +4,6 @@
  Define methods to import platform specific files.
 """
 
-import imp
 import importlib
 import string
 import sys
diff --git a/lib/dump_utils.py b/lib/dump_utils.py
index 1f00683..ec67dc9 100755
--- a/lib/dump_utils.py
+++ b/lib/dump_utils.py
@@ -4,7 +4,7 @@
 This file contains functions which are useful for processing BMC dumps.
 """
 
-import imp
+import importlib.util
 import os
 import sys
 
@@ -15,7 +15,9 @@
 from robot.libraries.BuiltIn import BuiltIn
 
 base_path = (
-    os.path.dirname(os.path.dirname(imp.find_module("gen_robot_print")[1]))
+    os.path.dirname(
+        os.path.dirname(importlib.util.find_spec("gen_robot_print").origin)
+    )
     + os.sep
 )
 sys.path.append(base_path + "data/")
diff --git a/lib/gen_call_robot.py b/lib/gen_call_robot.py
index 91231bf..4a8e2b0 100755
--- a/lib/gen_call_robot.py
+++ b/lib/gen_call_robot.py
@@ -5,7 +5,7 @@
 robot program calls.
 """
 
-import imp
+import importlib.util
 import os
 import re
 import subprocess
@@ -18,7 +18,9 @@
 import gen_valid as gv
 
 base_path = (
-    os.path.dirname(os.path.dirname(imp.find_module("gen_robot_print")[1]))
+    os.path.dirname(
+        os.path.dirname(importlib.util.find_spec("gen_robot_print").origin)
+    )
     + os.sep
 )
 
diff --git a/lib/logging_utils.py b/lib/logging_utils.py
index 4cd1898..92160cd 100644
--- a/lib/logging_utils.py
+++ b/lib/logging_utils.py
@@ -4,7 +4,7 @@
 Provide useful error log utility keywords.
 """
 
-import imp
+import importlib.util
 import os
 import sys
 
@@ -12,7 +12,9 @@
 from robot.libraries.BuiltIn import BuiltIn
 
 base_path = (
-    os.path.dirname(os.path.dirname(imp.find_module("gen_robot_print")[1]))
+    os.path.dirname(
+        os.path.dirname(importlib.util.find_spec("gen_robot_print").origin)
+    )
     + os.sep
 )
 sys.path.append(base_path + "data/")
diff --git a/lib/obmc_boot_test.py b/lib/obmc_boot_test.py
index 5b3d7de..5550277 100755
--- a/lib/obmc_boot_test.py
+++ b/lib/obmc_boot_test.py
@@ -5,7 +5,7 @@
 """
 
 import glob
-import imp
+import importlib.util
 import os
 import random
 import re
@@ -36,7 +36,9 @@
 from robot.utils import DotDict
 
 base_path = (
-    os.path.dirname(os.path.dirname(imp.find_module("gen_robot_print")[1]))
+    os.path.dirname(
+        os.path.dirname(importlib.util.find_spec("gen_robot_print").origin)
+    )
     + os.sep
 )
 sys.path.append(base_path + "extended/")
diff --git a/lib/state.py b/lib/state.py
index 00fa124..e48e8d8 100755
--- a/lib/state.py
+++ b/lib/state.py
@@ -27,7 +27,7 @@
 compared with the expected state.
 """
 
-import imp
+import importlib.util
 import os
 import re
 import sys
@@ -45,7 +45,9 @@
 gru.my_import_resource("rest_client.robot")
 
 base_path = (
-    os.path.dirname(os.path.dirname(imp.find_module("gen_robot_print")[1]))
+    os.path.dirname(
+        os.path.dirname(importlib.util.find_spec("gen_robot_print").origin)
+    )
     + os.sep
 )
 sys.path.append(base_path + "data/")
diff --git a/lib/utilities.py b/lib/utilities.py
index 1ec3b71..3c54441 100755
--- a/lib/utilities.py
+++ b/lib/utilities.py
@@ -3,7 +3,7 @@
 r"""
 Generic utility functions.
 """
-import imp
+import importlib.util
 import random
 import string
 import subprocess
@@ -12,6 +12,16 @@
 from robot.utils import DotDict
 
 
+def load_source(name, module_path):
+    r"""
+    import util to replace deprecated imp.load_source
+    """
+    spec = importlib.util.spec_from_file_location(name, module_path)
+    module = importlib.util.module_from_spec(spec)
+    spec.loader.exec_module(module)
+    return module
+
+
 def random_mac():
     r"""
     Return random mac address in the following format.
@@ -37,7 +47,7 @@
     r"""
     Return sensor matched ID name.
     """
-    m = imp.load_source("module.name", module_name)
+    m = load_source("module.name", module_name)
 
     for i in m.ID_LOOKUP["SENSOR"]:
         if m.ID_LOOKUP["SENSOR"][i] == value:
@@ -50,7 +60,7 @@
     r"""
     Return sensor matched ID name from inventory.
     """
-    m = imp.load_source("module.name", module_name)
+    m = load_source("module.name", module_name)
 
     value = string.replace(value, m.INVENTORY_ROOT, "<inventory_root>")
 
@@ -75,7 +85,7 @@
     """
 
     inventory_list = []
-    m = imp.load_source("module.name", module_name)
+    m = load_source("module.name", module_name)
 
     for i in m.ID_LOOKUP["FRU"]:
         s = m.ID_LOOKUP["FRU"][i]
@@ -98,7 +108,7 @@
     Return FRU URI(s) list of a given type from inventory.
     """
     inventory_list = []
-    m = imp.load_source("module.name", module_name)
+    m = load_source("module.name", module_name)
 
     for i in m.FRU_INSTANCES.keys():
         if m.FRU_INSTANCES[i]["fru_type"] == fru:
@@ -121,7 +131,7 @@
     Return VPD URI(s) list of a FRU type from inventory.
     """
     inventory_list = []
-    m = imp.load_source("module.name", module_name)
+    m = load_source("module.name", module_name)
 
     for i in m.ID_LOOKUP["FRU_STR"]:
         x = m.ID_LOOKUP["FRU_STR"][i]