Fix loading plugins from path with relative imports

Also:
- fixes `tox -e self` job. It was designed to ensure that relative
  imports are working, but ignored the error.
- changed `rally task sla-check` to return not zero code in case of
  finding non of workloads had been executed.

Change-Id: I723f81abdfbe7c71e9ec36aaf6f0936a42eac425
This commit is contained in:
Andrey Kurilin 2020-02-26 15:18:30 +02:00
parent 12404b8402
commit e9264de713
7 changed files with 27 additions and 15 deletions

View File

@ -31,7 +31,13 @@ Changed
* *path_or_url* plugin follows redirects while validating urls now. * *path_or_url* plugin follows redirects while validating urls now.
* Move *rally.common.sshutils* to *rally.utils.sshutils* * *rally task sla-check` fails if there is no data.
Deprecated
~~~~~~~~~~
* Module *rally.common.sshutils* is deprecated. Use *rally.utils.sshutils*
instead.
Removed Removed
~~~~~~~ ~~~~~~~

View File

@ -915,6 +915,8 @@ class TaskCommands(object):
else: else:
cliutils.print_list(data, ("benchmark", "pos", "criterion", cliutils.print_list(data, ("benchmark", "pos", "criterion",
"status", "detail")) "status", "detail"))
if not data:
return 2
return failed_criteria return failed_criteria
@cliutils.args("--uuid", type=str, dest="task_id", @cliutils.args("--uuid", type=str, dest="task_id",

View File

@ -132,6 +132,10 @@ def load_plugins(dir_or_file, depth=0):
LOG.info("Loading plugins from directories %s/*" % LOG.info("Loading plugins from directories %s/*" %
directory.rstrip("/")) directory.rstrip("/"))
for root, _dirs, files in os.walk(directory, followlinks=True): for root, _dirs, files in os.walk(directory, followlinks=True):
if root not in sys.path:
# this hack is required to support relative imports
sys.path.append(root)
for plugin in files: for plugin in files:
load_plugins(os.path.join(root, plugin), depth=1) load_plugins(os.path.join(root, plugin), depth=1)
@ -141,9 +145,10 @@ def load_plugins(dir_or_file, depth=0):
if depth: if depth:
msg = "\t" + msg msg = "\t" + msg
LOG.info(msg) LOG.info(msg)
module_name = os.path.splitext(plugin_file.split("/")[-1])[0]
try: try:
spec = importlib.util.spec_from_file_location( spec = importlib.util.spec_from_file_location(
plugin_file, plugin_file) module_name, plugin_file)
module = importlib.util.module_from_spec(spec) module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module) spec.loader.exec_module(module)
@ -155,5 +160,4 @@ def load_plugins(dir_or_file, depth=0):
LOG.warning("%(msg)s: %(e)s" % {"msg": msg, "e": e}) LOG.warning("%(msg)s: %(e)s" % {"msg": msg, "e": e})
return return
_loaded_modules.append(module) _loaded_modules.append(module)
LOG.info("\t Loaded module with plugins: %s" % LOG.info("\t Loaded module with plugins: %s" % module_name)
os.path.splitext(plugin_file.split("/")[-1])[0])

View File

@ -2,7 +2,7 @@
vars: vars:
results_dir: "{{ zuul.project.src_dir }}/.test_results/" results_dir: "{{ zuul.project.src_dir }}/.test_results/"
html_report: "{{ tox_env }}_report.html" html_report: "{{ tox_env }}_report.html"
json_report: "{{ tox_env }}_report.html" json_report: "{{ tox_env }}_report.json"
tasks: tasks:
- shell: "ls {{ results_dir }}" - shell: "ls {{ results_dir }}"
register: results_dir_stat register: results_dir_stat

View File

@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
"""Simple app based on rally api for testing porpuses""" """Simple app based on rally api for testing purpose"""
import sys import sys

View File

@ -25,10 +25,15 @@ TMP_RALLY_DB="/tmp/self-rally-$RND.sqlite"
DBCONNSTRING="sqlite:///$TMP_RALLY_DB" DBCONNSTRING="sqlite:///$TMP_RALLY_DB"
RALLY="rally --config-file $TMP_RALLY_CONF" RALLY="rally --config-file $TMP_RALLY_CONF"
# Create temp db # Create temp cfg
cp etc/rally/rally.conf.sample $TMP_RALLY_CONF cp etc/rally/rally.conf.sample $TMP_RALLY_CONF
sed -i.bak "s|#connection =.*|connection = \"$DBCONNSTRING\"|" $TMP_RALLY_CONF sed -i.bak "s|#connection =.*|connection = \"$DBCONNSTRING\"|" $TMP_RALLY_CONF
rally --config-file $TMP_RALLY_CONF db create
# ensure plugins loading
$RALLY --debug --plugin-paths=$PLUGIN_PATHS plugin show --name FakePlugin.testplugin
# Create db
$RALLY db create
# Create self deployment # Create self deployment
$RALLY -d env create --name=self $RALLY -d env create --name=self
@ -44,10 +49,5 @@ set -e
$RALLY task report --html-static --out $HTML_REPORT $RALLY task report --html-static --out $HTML_REPORT
$RALLY task report --json --out $JSON_REPORT $RALLY task report --json --out $JSON_REPORT
if [ -n "$ZUUL_PROJECT" ]; then
gzip -9 -f $HTML_REPORT
gzip -9 -f $JSON_REPORT
fi
# Check sla (this may fail the job) # Check sla (this may fail the job)
$RALLY task sla-check $RALLY task sla-check

View File

@ -95,7 +95,7 @@ class LoadExtraModulesTestCase(test.TestCase):
test_path = "/somewhere" test_path = "/somewhere"
discover.load_plugins(test_path) discover.load_plugins(test_path)
expected = [ expected = [
mock.call(p, p) mock.call(p.rsplit("/", 1)[1][:-3], p)
for p in ("/somewhere/plugin1.py", "/somewhere/subdir/plugin2.py", for p in ("/somewhere/plugin1.py", "/somewhere/subdir/plugin2.py",
"/somewhere/subdir/subsubdir/plugin3.py") "/somewhere/subdir/subsubdir/plugin3.py")
] ]
@ -111,7 +111,7 @@ class LoadExtraModulesTestCase(test.TestCase):
path = "/somewhere/plugin.py" path = "/somewhere/plugin.py"
discover.load_plugins(path) discover.load_plugins(path)
mock_spec_from_file_location.assert_called_once_with(path, path) mock_spec_from_file_location.assert_called_once_with("plugin", path)
mock_module_from_spec.assert_called_once_with( mock_module_from_spec.assert_called_once_with(
mock_spec_from_file_location.return_value) mock_spec_from_file_location.return_value)