Source code for spinnaker_testbase.script_checker
# Copyright (c) 2017 The University of Manchester
#
# 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
#
# https://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.
import os
import sys
import time
from typing import List, Optional
from unittest import SkipTest
import matplotlib
import matplotlib.pyplot as pyplot
from .root_test_case import RootTestCase
matplotlib.use('Agg')
# pylint: disable=invalid-name
script_checker_shown = False
# This is a global function as pydevd calls _needsmain when debugging
def mockshow() -> None:
"""
This will replace pyplot.show during script tests
This avoids the plots from printed but checks the script tried to
"""
# pylint: disable=global-statement
global script_checker_shown
script_checker_shown = True
[docs]
class ScriptChecker(RootTestCase):
"""
Will run a script. Typically as part of Integration Tests.
"""
def _script_path(self, script: str) -> str:
class_file = sys.modules[self.__module__].__file__
assert class_file is not None
integration_tests_directory = os.path.dirname(class_file)
root_dir = os.path.dirname(integration_tests_directory)
assert root_dir is not None
return os.path.join(root_dir, script)
[docs]
def check_script(self, script: str, broken_msg: Optional[str] = None,
skip_exceptions: Optional[List[type]] = None,
use_script_dir: bool = True) -> None:
"""
Checks/runs a script, timing the run.
Includes a work around for matplotlib
so it does not actually try to plot
:param script: relative path to the file to run
:param broken_msg:
message to print instead of raising an exception;
no current use-case known
:param skip_exceptions:
list of exception classes to convert in SkipTest
:param use_script_dir:
If True this checker will change directory into the scripts
directory so that the local cfg file is read.
If False the caller is responsible for changing into the directory
containing any relative cfg.
"""
# pylint: disable=global-statement
global script_checker_shown
script_path = self._script_path(script)
if use_script_dir:
self._setup(script_path)
# pylint: disable=import-outside-toplevel
plotting = "import matplotlib.pyplot" in (
open(script_path, encoding="utf-8").read())
if plotting:
script_checker_shown = False
pyplot.show = mockshow
from runpy import run_path
try:
start = time.time()
self.runsafe(lambda: run_path(script_path),
skip_exceptions=skip_exceptions)
duration = time.time() - start
self.report(f"{duration} for {script}", "scripts_ran_successfully")
if plotting:
if not script_checker_shown:
raise SkipTest(f"{script} did not plot")
except SkipTest:
raise
except Exception as ex: # pylint: disable=broad-except
if broken_msg:
self.report(script, broken_msg)
else:
print(f"Error on {script}")
raise ex