source: mod_gnutls/test/mgstest/hooks.py

mod_gnutls/0.11.0
Last change on this file was 60ed7d1, checked in by Fiona Klute <fiona.klute@…>, 7 months ago

Allow the prepare_env hook to return a cleanup callback

  • Property mode set to 100644
File size: 3.7 KB
Line 
1# Copyright 2019-2020 Fiona Klute
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Test case hooks for mod_gnutls tests.
16
17Test cases can implement hooks that (depending on the hook) override
18or supplement the default test run behavior. Three hooks are currently
19supported:
20
21    prepare_env:
22
23        This hook runs before the test services are started. It serves
24        two purposes:
25
26        1. Check special precondition the test might need
27        (e.g. availability of a certain Apache module), and raise
28        unittest.SkipTest to skip the test case if they are not met.
29
30        2. Set any additional environment variables the test might
31        need.
32
33        If the hook creates any resources that need to be cleaned up
34        after the test (e.g. delete a temporary file), it should
35        return a callable which performs the cleanup. That callable
36        will be called without arguments when the test services are
37        stopped.
38
39    run_connection:
40
41        Will be called *instead* of mgstests.tests.run_test_conf() and
42        is expected to run whatever client actions the test
43        requires. This hook receives three parameters:
44
45        * testname: string containing the test name
46        * conn_log: file object for connection logging
47        * response_log: file object for HTTP response logging
48
49    post_check:
50
51        Execute additional checks if desired. This hook is called
52        after the test client run and after the test environment
53        terminates. This hook receives two parameters:
54
55        * conn_log: file object with connection log data
56        * response_log: file object with HTTP response log data
57
58        With the default client implementation conn_log will contain
59        gnutls-cli output, and response_log the full HTTP responses
60        (including status line and headers).
61
62"""
63
64import importlib.util
65import inspect
66import os.path
67
68hooks = [
69    'prepare_env',
70    'run_connection',
71    'post_check'
72]
73
74class Plugin:
75    """Represents a set of hooks.
76
77    All attribute names listed in the "hooks" field are guaranteed to
78    exist in an instance of this class, with the value of each being
79    either None or a function.
80
81    """
82    def __init__(self, module=None):
83        self.module = module
84        for hook in hooks:
85            if module:
86                func = getattr(module, hook, None)
87                if func and not inspect.isfunction(func):
88                    raise TypeError(f'{hook} in plugin module must be '
89                                    'a function!')
90                setattr(self, hook, func)
91            else:
92                setattr(self, hook, None)
93
94def load_module_file(file_path, module_name):
95    """Load a module from a file path."""
96    spec = importlib.util.spec_from_file_location(module_name, file_path)
97    module = importlib.util.module_from_spec(spec)
98    spec.loader.exec_module(module)
99    return module
100
101def load_hooks_plugin(file_path, module_name='mgstest.plugin'):
102    """Load a hooks plugin module from the given path, if it
103    exists. Returns a Plugin instance without any hooks if the module
104    file does not exist.
105    """
106    if os.path.exists(file_path):
107        return Plugin(module=load_module_file(file_path, module_name))
108    else:
109        return Plugin()
Note: See TracBrowser for help on using the repository browser.