old_contents: """Test case hooks for mod_gnutls tests.
  
  Test cases can implement hooks that (depending on the hook) override
  or supplement the default test run behavior. Two hooks are currently
  supported:
  
      run_connection:
  
          Will be called *instead* of mgstests.tests.run_test_conf() and
          is expected to run whatever client actions the test
          requires. This hook receives three parameters:
  
          * testname: string containing the test name
          * conn_log: file object for connection logging
          * response_log: file object for HTTP response logging
  
  
      post_check:
  
          Execute additional checks if desired. This hook is called
          after the test client run and after the test environment
          terminates. This hook receives two parameters:
  
          * conn_log: file object with connection log data
          * response_log: file object with HTTP response log data
  
          With the default client implementation conn_log will contain
          gnutls-cli output, and response_log the full HTTP responses
          (including status line and headers).
  
  """
  
  import importlib.util
  import inspect
  import os.path
  
  hooks = [
      'prepare_env',
      'run_connection',
      'post_check'
  ]
  
  class Plugin:
      """Represents a set of hooks.
  
      All attribute names listed in the "hooks" field are guaranteed to
      exist in an instance of this class, with the value of each being
      either None or a function.
  
      """
      def __init__(self, module=None):
          self.module = module
          for hook in hooks:
              if module:
                  func = getattr(module, hook, None)
                  if func and not inspect.isfunction(func):
                      raise TypeError(f'{hook} in plugin module must be '
                                      'a function!')
                  setattr(self, hook, func)
              else:
                  setattr(self, hook, None)
  
  def load_module_file(file_path, module_name):
      """Load a module from a file path."""
      spec = importlib.util.spec_from_file_location(module_name, file_path)
      module = importlib.util.module_from_spec(spec)
      spec.loader.exec_module(module)
      return module
  
  def load_hooks_plugin(file_path, module_name='mgstest.plugin'):
      """Load a hooks plugin module from the given path, if it
      exists. Returns a Plugin instance without any hooks if the module
      file does not exist.
      """
      if os.path.exists(file_path):
          return Plugin(module=load_module_file(file_path, module_name))
      else:
          return Plugin()
  
new_contents: # Copyright 2019-2020 Fiona Klute
  #
  # 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.
  
  """Test case hooks for mod_gnutls tests.
  
  Test cases can implement hooks that (depending on the hook) override
  or supplement the default test run behavior. Two hooks are currently
  supported:
  
      run_connection:
  
          Will be called *instead* of mgstests.tests.run_test_conf() and
          is expected to run whatever client actions the test
          requires. This hook receives three parameters:
  
          * testname: string containing the test name
          * conn_log: file object for connection logging
          * response_log: file object for HTTP response logging
  
  
      post_check:
  
          Execute additional checks if desired. This hook is called
          after the test client run and after the test environment
          terminates. This hook receives two parameters:
  
          * conn_log: file object with connection log data
          * response_log: file object with HTTP response log data
  
          With the default client implementation conn_log will contain
          gnutls-cli output, and response_log the full HTTP responses
          (including status line and headers).
  
  """
  
  import importlib.util
  import inspect
  import os.path
  
  hooks = [
      'prepare_env',
      'run_connection',
      'post_check'
  ]
  
  class Plugin:
      """Represents a set of hooks.
  
      All attribute names listed in the "hooks" field are guaranteed to
      exist in an instance of this class, with the value of each being
      either None or a function.
  
      """
      def __init__(self, module=None):
          self.module = module
          for hook in hooks:
              if module:
                  func = getattr(module, hook, None)
                  if func and not inspect.isfunction(func):
                      raise TypeError(f'{hook} in plugin module must be '
                                      'a function!')
                  setattr(self, hook, func)
              else:
                  setattr(self, hook, None)
  
  def load_module_file(file_path, module_name):
      """Load a module from a file path."""
      spec = importlib.util.spec_from_file_location(module_name, file_path)
      module = importlib.util.module_from_spec(spec)
      spec.loader.exec_module(module)
      return module
  
  def load_hooks_plugin(file_path, module_name='mgstest.plugin'):
      """Load a hooks plugin module from the given path, if it
      exists. Returns a Plugin instance without any hooks if the module
      file does not exist.
      """
      if os.path.exists(file_path):
          return Plugin(module=load_module_file(file_path, module_name))
      else:
          return Plugin()
  
subject: Add forgotten license header