tests: preload api files
When sanity test is not done, API files are not loaded until the first test case is run. Hence, it is not possible to use enums, etc. outside of a test class. By preloading API files before running any tests, it prevents its issue. Type: fix Change-Id: I8730150374e6c5f8d6933ec037811372ac2a8da0 Signed-off-by: Maxime Peim <mpeim@cisco.com>
This commit is contained in:

committed by
Dave Wallace

parent
87241fefd9
commit
77caeb1b19
@ -24,8 +24,7 @@ from vpp_papi import vpp_transport_shmem
|
||||
|
||||
class TestVppPapiVPPApiClient(unittest.TestCase):
|
||||
def test_getcontext(self):
|
||||
vpp_papi.VPPApiClient.apidir = "."
|
||||
c = vpp_papi.VPPApiClient(testmode=True, use_socket=True)
|
||||
c = vpp_papi.VPPApiClient(apidir=".", testmode=True, use_socket=True)
|
||||
|
||||
# reset initialization at module load time.
|
||||
c.get_context.context = mp.Value(ctypes.c_uint, 0)
|
||||
@ -39,8 +38,7 @@ class TestVppPapiVPPApiClientMp(unittest.TestCase):
|
||||
# run_tests.py (eg. make test TEST_JOBS=10)
|
||||
|
||||
def test_get_context_mp(self):
|
||||
vpp_papi.VPPApiClient.apidir = "."
|
||||
c = vpp_papi.VPPApiClient(testmode=True, use_socket=True)
|
||||
c = vpp_papi.VPPApiClient(apidir=".", testmode=True, use_socket=True)
|
||||
|
||||
# reset initialization at module load time.
|
||||
c.get_context.context = mp.Value(ctypes.c_uint, 0)
|
||||
|
@ -281,16 +281,15 @@ class VPPApiJSONFiles:
|
||||
|
||||
@classmethod
|
||||
def process_json_file(self, apidef_file):
|
||||
api = json.load(apidef_file)
|
||||
return self._process_json(api)
|
||||
return self._process_json(apidef_file.read())
|
||||
|
||||
@classmethod
|
||||
def process_json_str(self, json_str):
|
||||
api = json.loads(json_str)
|
||||
return self._process_json(api)
|
||||
return self._process_json(json_str)
|
||||
|
||||
@staticmethod
|
||||
def _process_json(api): # -> Tuple[Dict, Dict]
|
||||
def _process_json(json_str): # -> Tuple[Dict, Dict]
|
||||
api = json.loads(json_str)
|
||||
types = {}
|
||||
services = {}
|
||||
messages = {}
|
||||
@ -380,6 +379,30 @@ class VPPApiJSONFiles:
|
||||
pass
|
||||
return messages, services
|
||||
|
||||
@staticmethod
|
||||
def load_api(apifiles=None, apidir=None):
|
||||
messages = {}
|
||||
services = {}
|
||||
if not apifiles:
|
||||
# Pick up API definitions from default directory
|
||||
try:
|
||||
if isinstance(apidir, list):
|
||||
apifiles = []
|
||||
for d in apidir:
|
||||
apifiles += VPPApiJSONFiles.find_api_files(d)
|
||||
else:
|
||||
apifiles = VPPApiJSONFiles.find_api_files(apidir)
|
||||
except (RuntimeError, VPPApiError):
|
||||
raise VPPRuntimeError
|
||||
|
||||
for file in apifiles:
|
||||
with open(file) as apidef_file:
|
||||
m, s = VPPApiJSONFiles.process_json_file(apidef_file)
|
||||
messages.update(m)
|
||||
services.update(s)
|
||||
|
||||
return apifiles, messages, services
|
||||
|
||||
|
||||
class VPPApiClient:
|
||||
"""VPP interface.
|
||||
@ -394,7 +417,6 @@ class VPPApiClient:
|
||||
these messages in a background thread.
|
||||
"""
|
||||
|
||||
apidir = None
|
||||
VPPApiError = VPPApiError
|
||||
VPPRuntimeError = VPPRuntimeError
|
||||
VPPValueError = VPPValueError
|
||||
@ -405,6 +427,7 @@ class VPPApiClient:
|
||||
self,
|
||||
*,
|
||||
apifiles=None,
|
||||
apidir=None,
|
||||
testmode=False,
|
||||
async_thread=True,
|
||||
logger=None,
|
||||
@ -439,6 +462,7 @@ class VPPApiClient:
|
||||
self.id_msgdef = []
|
||||
self.header = VPPType("header", [["u16", "msgid"], ["u32", "client_index"]])
|
||||
self.apifiles = []
|
||||
self.apidir = apidir
|
||||
self.event_callback = None
|
||||
self.message_queue = queue.Queue()
|
||||
self.read_timeout = read_timeout
|
||||
@ -449,29 +473,15 @@ class VPPApiClient:
|
||||
self._apifiles = apifiles
|
||||
self.stats = {}
|
||||
|
||||
if not apifiles:
|
||||
# Pick up API definitions from default directory
|
||||
try:
|
||||
if isinstance(self.apidir, list):
|
||||
apifiles = []
|
||||
for d in self.apidir:
|
||||
apifiles += VPPApiJSONFiles.find_api_files(d)
|
||||
else:
|
||||
apifiles = VPPApiJSONFiles.find_api_files(self.apidir)
|
||||
except (RuntimeError, VPPApiError):
|
||||
# In test mode we don't care that we can't find the API files
|
||||
if testmode:
|
||||
apifiles = []
|
||||
else:
|
||||
raise VPPRuntimeError
|
||||
|
||||
for file in apifiles:
|
||||
with open(file) as apidef_file:
|
||||
m, s = VPPApiJSONFiles.process_json_file(apidef_file)
|
||||
self.messages.update(m)
|
||||
self.services.update(s)
|
||||
|
||||
self.apifiles = apifiles
|
||||
try:
|
||||
self.apifiles, self.messages, self.services = VPPApiJSONFiles.load_api(
|
||||
apifiles, apidir
|
||||
)
|
||||
except VPPRuntimeError as e:
|
||||
if testmode:
|
||||
self.apifiles = []
|
||||
else:
|
||||
raise e
|
||||
|
||||
# Basic sanity check
|
||||
if len(self.messages) == 0 and not testmode:
|
||||
|
@ -259,6 +259,12 @@ ifneq ($(findstring $(DECODE_PCAPS),1 y yes),)
|
||||
ARG18=--decode-pcaps
|
||||
endif
|
||||
|
||||
ifneq ($(findstring $(API_PRELOAD),1 y yes),)
|
||||
ARG19=--api-preload
|
||||
else
|
||||
ARG19=
|
||||
endif
|
||||
|
||||
EXC_PLUGINS_ARG=
|
||||
ifneq ($(VPP_EXCLUDED_PLUGINS),)
|
||||
# convert the comma-separated list into N invocations of the argument to exclude a plugin
|
||||
@ -267,7 +273,7 @@ endif
|
||||
|
||||
|
||||
|
||||
EXTRA_ARGS=$(ARG0) $(ARG1) $(ARG2) $(ARG3) $(ARG4) $(ARG5) $(ARG6) $(ARG7) $(ARG8) $(ARG9) $(ARG10) $(ARG11) $(ARG12) $(ARG13) $(ARG14) $(ARG15) $(ARG16) $(ARG17) $(ARG18)
|
||||
EXTRA_ARGS=$(ARG0) $(ARG1) $(ARG2) $(ARG3) $(ARG4) $(ARG5) $(ARG6) $(ARG7) $(ARG8) $(ARG9) $(ARG10) $(ARG11) $(ARG12) $(ARG13) $(ARG14) $(ARG15) $(ARG16) $(ARG17) $(ARG18) $(ARG19)
|
||||
|
||||
RUN_TESTS_ARGS=--failed-dir=$(FAILED_DIR) --verbose=$(V) --jobs=$(TEST_JOBS) --filter=$(TEST) --retries=$(RETRIES) --venv-dir=$(VENV_PATH) --vpp-ws-dir=$(WS_ROOT) --vpp-tag=$(TAG) --rnd-seed=$(RND_SEED) --vpp-worker-count="$(VPP_WORKER_COUNT)" --keep-pcaps $(PLUGIN_PATH_ARGS) $(EXC_PLUGINS_ARG) $(TEST_PLUGIN_PATH_ARGS) $(EXTRA_ARGS)
|
||||
RUN_SCRIPT_ARGS=--python-opts=$(PYTHON_OPTS)
|
||||
|
@ -201,6 +201,7 @@ parser.add_argument(
|
||||
parser.add_argument(
|
||||
"--sanity", action="store_true", help="perform sanity vpp run before running tests"
|
||||
)
|
||||
parser.add_argument("--api-preload", action="store_true", help="preload API files")
|
||||
|
||||
parser.add_argument(
|
||||
"--force-foreground",
|
||||
|
@ -14,6 +14,7 @@ from multiprocessing import Process, Pipe, get_context
|
||||
from multiprocessing.queues import Queue
|
||||
from multiprocessing.managers import BaseManager
|
||||
from config import config, num_cpus, available_cpus, max_vpp_cpus
|
||||
from vpp_papi import VPPApiJSONFiles
|
||||
from asfframework import (
|
||||
VppTestRunner,
|
||||
get_testcase_doc_name,
|
||||
@ -906,6 +907,9 @@ def parse_results(results):
|
||||
if __name__ == "__main__":
|
||||
print(f"Config is: {config}")
|
||||
|
||||
if config.api_preload:
|
||||
VPPApiJSONFiles.load_api(apidir=config.extern_apidir + [config.vpp_install_dir])
|
||||
|
||||
if config.sanity:
|
||||
print("Running sanity test case.")
|
||||
try:
|
||||
|
@ -236,11 +236,8 @@ class VppPapiProvider(object):
|
||||
self._expect_api_retval = self._zero
|
||||
self._expect_stack = []
|
||||
|
||||
# install_dir is a class attribute. We need to set it before
|
||||
# calling the constructor.
|
||||
VPPApiClient.apidir = config.extern_apidir + [config.vpp_install_dir]
|
||||
|
||||
self.vpp = VPPApiClient(
|
||||
apidir=config.extern_apidir + [config.vpp_install_dir],
|
||||
logger=test_class.logger,
|
||||
read_timeout=read_timeout,
|
||||
use_socket=True,
|
||||
|
Reference in New Issue
Block a user