VOL-4805
This script is an inital attempt at capturing and documenting testing
resources for interactive and programatic retrieval. Command line
arguments and eventual filesystem based detection will hints for a
suite of tests to run to evaluate VOLTHA code changes.
make check: run python unit tests
usage:
% flog.py --help
% flog.py --usage
% flog.py --type regression
% flog.py --attr olt
Recreate patch: start over
o approval given by: daf & torsten
o a cycle of squashing roaches reported by lint checking resulted
in multiple conflicting patches in gerrit. Abandon the mess and
submit a clean patch.
o Only delta introduced is using the updated standard copyright notice.
o git merge to get branch and master back in sync.
Change-Id: I24292f2b72d134879939f43a84b31ab153d10fa9
diff --git a/scripts/flog/main/__init__.py b/scripts/flog/main/__init__.py
new file mode 100644
index 0000000..b8a587e
--- /dev/null
+++ b/scripts/flog/main/__init__.py
@@ -0,0 +1,37 @@
+# -*- python -*-
+"""Augment module searchpath and existence indicates directory is a module."""
+
+# -----------------------------------------------------------------------
+# Copyright 2022 Open Networking Foundation (ONF) and the ONF Contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+##-------------------##
+##---] IMPORTS [---##
+##-------------------##
+import sys
+from pathlib import Path
+
+## ---------------------------------------
+## Artificial scope created for local vars
+## ---------------------------------------
+# pylint: disable=invalid-name
+# pylint: disable=using-constant-test
+if True:
+ root = '../..'
+ mod_path = Path(root).resolve().as_posix()
+ if mod_path not in sys.path:
+ sys.path.insert(0, mod_path)
+
+# [EOF]
diff --git a/scripts/flog/main/argparse.py b/scripts/flog/main/argparse.py
new file mode 100644
index 0000000..01cdc4b
--- /dev/null
+++ b/scripts/flog/main/argparse.py
@@ -0,0 +1,181 @@
+# -*- python -*-
+'''A module for parsing script command line arguments.
+
+..seealso: https://docs.python.org/3/library/argparse.html##
+'''
+
+# -----------------------------------------------------------------------
+# Copyright 2022 Open Networking Foundation (ONF) and the ONF Contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+##-------------------##
+##---] GLOBALS [---##
+##-------------------##
+ARGV = None
+namespace = None
+
+##-------------------##
+##---] IMPORTS [---##
+##-------------------##
+import argparse
+
+from flog.main import utils as main_utils
+from flog.main import help as main_help
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+def get_argv():
+ """Retrieve parsed command line switches.
+
+ ..pre: getopts() was called earlier.
+
+ :return: Parsed command line argument storage
+ :rtype : dict
+ """
+
+ global ARGV
+ global namespace
+
+ if ARGV is None:
+ # Normalize argspace/namespace into a getopt/dictionary
+ # Program wide syntax edits needed: args['foo'] => args.foo
+ arg_dict = {}
+ for arg in vars(namespace):
+ arg_dict[arg] = getattr(namespace, arg)
+ ARGV = arg_dict
+
+ return ARGV
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+def getopts(argv, debug=None) -> None:
+ """Parse command line args, check options and pack into a hashmap
+
+ :param argv: values passed on the command line
+ :param debug: optional flag to enable debug mode
+
+ :return: Digested command line arguments
+ :rtype : dict
+
+ :raises ValueError
+
+ .. versionadded:: 1.0
+ """
+
+ global namespace
+
+ iam = main_utils.iam()
+
+ if debug is None:
+ debug = False
+
+ parser = argparse.ArgumentParser\
+ (
+ description = '''Report test dependencies based on selection criteria.'''
+ # epilog = 'extra-help-text'
+ )
+
+ ## -----------------------------------------------------------------------
+ ## [TEST: categories]
+ ## -----------------------------------------------------------------------
+ parser.add_argument('--attr',
+ action = 'append',
+ default = [],
+ choices=\
+ [
+ 'olt', # optical line termination
+ #
+ 'onu', # optical network unit
+ #
+ 'epon',
+ 'pon', # passive optical network
+ 'gpon', # gigabit-pon
+ 'xpon',
+ ],
+ help = 'Enable testing by attribute',
+ )
+
+ ## -----------------------------------------------------------------------
+ ## [TEST:types]
+ ## -----------------------------------------------------------------------
+ parser.add_argument('--type',
+ action = 'append',
+ default = [],
+ choices=\
+ [
+ 'burnin', # profile, stress testing
+ 'integration', # trigger inter-dependencies
+ 'oink', # kitchen sink testing
+ 'regression', # have we broken the renaissance ?
+ 'scale', #
+ 'system', #
+ 'smoke', # quick: 60s > [n]
+ 'standalone', # dependency-less tests
+ 'suite', #
+ 'unit', # module/api/narrow focus.
+ ],
+ help = 'Enable testing by category',
+ )
+
+ ## -----------------------------------------------------------------------
+ ## [FILTER]
+ ## -----------------------------------------------------------------------
+ parser.add_argument('--excl',
+ action = 'append',
+ default = [],
+ help = 'FILTER: Probe resources to exclude',
+ )
+ parser.add_argument('--incl',
+ action = 'append',
+ default = [],
+ help = 'FILTER: Probe resources to include',
+ )
+
+ ## -----------------------------------------------------------------------
+ ## [MODES]
+ ## -----------------------------------------------------------------------
+ parser.add_argument('--debug',
+ action = 'store_true',
+ default = False,
+ help = 'Enable debug mode',
+ )
+
+ parser.add_argument('--trace',
+ action = 'append',
+ default = [],
+ help = 'Enable python debugging to trace a named resource.',
+ )
+
+ parser.add_argument('--usage',
+ action = 'store_true',
+ default = False,
+ help = 'Show usage examples',
+ )
+
+ parser.add_argument('--version', action='version', version='%(prog)s 1.0')
+
+
+ namespace = parser.parse_args()
+
+ # --------------------------------------------------------------
+ # [TODO] update --usage to accept a value, display context help.
+ # --------------------------------------------------------------
+ if namespace.usage:
+ main_help.usage()
+
+ return
+
+# [EOF]
+
diff --git a/scripts/flog/main/help.py b/scripts/flog/main/help.py
new file mode 100644
index 0000000..0141461
--- /dev/null
+++ b/scripts/flog/main/help.py
@@ -0,0 +1,71 @@
+# -*- python -*-
+# -----------------------------------------------------------------------
+# Copyright 2022 Open Networking Foundation (ONF) and the ONF Contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+##-------------------##
+##---] IMPORTS [---##
+##-------------------##
+import __main__
+import os
+import sys
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+def show_examples():
+ '''Display examples of command usage'''
+
+ cmd = os.path.basename(__main__.__file__)
+
+ print('''
+%% %s
+ Run all tests (default)
+
+%% %s --type regression
+ Run only regression tests.
+
+%% %s --type smoke
+ Run a quick battery of tests.
+
+%% %s --type suite --test unit --attr olt --attr onu
+ Run module tests for olt and onu.
+
+%% %s --type regression --attr gpon
+ Run regression tests for gpon logic.
+''' % (cmd, cmd, cmd, cmd, cmd))
+# print( (cmd) * 5) # syntax ?!?
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+def usage():
+ """Display command arguments and usage
+
+ :param err: Error to display due to invalid arg parsing.
+ :type err: String
+
+ :param arg: --help* command line argument digested by argparse.py
+ :type arg: String
+
+ :raises ValueError
+
+ ...versionadded: 1.1
+ """
+
+ cmd = os.path.basename(__main__.__file__)
+ print("USAGE: %s" % cmd)
+ show_examples()
+ sys.exit(0)
+
+# EOF
diff --git a/scripts/flog/main/test/__init__.py b/scripts/flog/main/test/__init__.py
new file mode 100644
index 0000000..4b4c0b2
--- /dev/null
+++ b/scripts/flog/main/test/__init__.py
@@ -0,0 +1,37 @@
+# -*- python -*-
+"""Augment module searchpath and existence indicates directory is a module."""
+
+# -----------------------------------------------------------------------
+# Copyright 2022 Open Networking Foundation (ONF) and the ONF Contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+##-------------------##
+##---] IMPORTS [---##
+##-------------------##
+import sys
+from pathlib import Path
+
+## ---------------------------------------
+## Artificial scope created for local vars
+## ---------------------------------------
+# pylint: disable=invalid-name
+# pylint: disable=using-constant-test
+if True:
+ root = '../../..'
+ mod_path = Path(root).resolve().as_posix()
+ if mod_path not in sys.path:
+ sys.path.insert(0, mod_path)
+
+# [EOF]
diff --git a/scripts/flog/main/test/test_file_utils.py b/scripts/flog/main/test/test_file_utils.py
new file mode 100644
index 0000000..b583900
--- /dev/null
+++ b/scripts/flog/main/test/test_file_utils.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+'''Unit test for main/utils.py'''
+
+# -----------------------------------------------------------------------
+# Copyright 2022 Open Networking Foundation (ONF) and the ONF Contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+##-------------------##
+##---] GLOBALS [---##
+##-------------------##
+
+##-------------------##
+##---] IMPORTS [---##
+##-------------------##
+import unittest
+
+from flog.main import utils as main_utils
+
+
+class TestStringMethods(unittest.TestCase):
+
+ ## -----------------------------------------------------------------------
+ ## -----------------------------------------------------------------------
+ def test_iam(self):
+
+ iam = main_utils.iam()
+ self.assertIn('test_iam', iam)
+ self.assertTrue(len(iam) > 4)
+
+##----------------##
+##---] MAIN [---##
+##----------------##
+if __name__ == "__main__":
+ main()
+
+# [EOF]
diff --git a/scripts/flog/main/utils.py b/scripts/flog/main/utils.py
new file mode 100644
index 0000000..7fd2eeb
--- /dev/null
+++ b/scripts/flog/main/utils.py
@@ -0,0 +1,70 @@
+# -*- python -*-
+## -----------------------------------------------------------------------
+## Intent: This module contains general helper methods
+## -----------------------------------------------------------------------
+
+# -----------------------------------------------------------------------
+# Copyright 2022 Open Networking Foundation (ONF) and the ONF Contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+##-------------------##
+##---] IMPORTS [---##
+##-------------------##
+import sys
+import pprint
+
+## ---------------------------------------------------------------------------
+## ---------------------------------------------------------------------------
+def iam():
+ """Return name of a called method."""
+
+ func_name = sys._getframe(1).f_code.co_name # pylint: disable=protected-access
+ iam = "%s::%s" % (__name__, func_name)
+ return iam
+
+## -----------------------------------------------------------------------
+## Intent: Display a message then exit with non-zero status.
+## This method cannot be intercepted by try/except
+## -----------------------------------------------------------------------
+def error(msg, exit_with=None, fatal=None):
+ """Display a message then exit with non-zero status.
+
+ :param msg: Error mesage to display.
+ :type msg: string
+
+ :param exit_with: Shell exit status.
+ :type exit_with: int, optional (default=2)
+
+ :param fatal: When true raise an exception.
+ :type fatal: bool (default=False)
+
+ """
+
+ if exit_with is None:
+ exit_with = 2
+
+ if fatal is None:
+ fatal = false
+
+ if msg:
+ if fatal:
+ raise Exception("ERROR: %s" % msg)
+ else:
+ print("")
+ print("ERROR: %s" % msg)
+
+ sys.exit(exit_with)
+
+# EOF