github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/acceptancetests/assess_destroy_model.py (about)

     1  #!/usr/bin/env python
     2  """Assess if Juju tracks the model when the current model is destroyed."""
     3  
     4  from __future__ import print_function
     5  
     6  import argparse
     7  import logging
     8  import sys
     9  import subprocess
    10  
    11  from deploy_stack import (
    12      BootstrapManager,
    13      )
    14  from utility import (
    15      add_basic_testing_arguments,
    16      configure_logging,
    17      JujuAssertionError,
    18      add_model,
    19      get_current_model,
    20      )
    21  
    22  
    23  __metaclass__ = type
    24  
    25  
    26  log = logging.getLogger("assess_destroy_model")
    27  
    28  TEST_MODEL = 'test-tmp-env'
    29  
    30  
    31  def assess_destroy_model(client):
    32      """Tests if Juju tracks the model properly through deletion.
    33  
    34      In normal behavior Juju should drop the current model selection if that
    35      model is destroyed. This will fail if Juju does not drop it's current
    36      selection.
    37  
    38      :param client: Jujupy ModelClient object
    39      """
    40  
    41      current_model = get_current_model(client)
    42      controller = get_current_controller(client)
    43      log.info('Current model: {}'.format(current_model))
    44  
    45      new_client = add_model(client)
    46      destroy_model(client, new_client)
    47  
    48      log.info('Juju successfully dropped its current model. '
    49               'Switching to {} to complete test'.format(current_model))
    50      switch_model(client, current_model, controller)
    51  
    52      log.info('SUCCESS')
    53  
    54  
    55  def destroy_model(client, new_client):
    56      log.info('Destroying model "{}"'.format(TEST_MODEL))
    57      new_client.destroy_model()
    58      old_model = get_current_model(client)
    59      if not old_model:
    60          error = 'Juju unset model after it was destroyed'
    61          raise JujuAssertionError(error)
    62      try:
    63          client.get_juju_output('status', include_e=False)
    64      except subprocess.CalledProcessError as e:
    65          if b'{} not found'.format(old_model) not in e.stderr:
    66              error = 'unexpected error calling status\n{}'.format(e.stderr)
    67              raise JujuAssertionError(error)
    68      else:
    69          error = 'model still valid after it was destroyed'
    70          raise JujuAssertionError(error)
    71  
    72  
    73  def switch_model(client, current_model, current_controller):
    74      """Switches back to the old model.
    75  
    76      :param client: Jujupy ModelClient object
    77      :param current_model: String name of initial testing model
    78      :param current_controller: String name of testing controller
    79      """
    80      client.switch(model=current_model, controller=current_controller)
    81      new_model = get_current_model(client)
    82      if new_model == current_model:
    83          log.info('Current model and switch target match')
    84      else:
    85          error = ('Juju failed to switch back to existing model. '
    86                   'Expected {} got {}'.format(TEST_MODEL, new_model))
    87          raise JujuAssertionError(error)
    88  
    89  
    90  def get_current_controller(client):
    91      """Gets the current controller from Juju's list-models command.
    92  
    93      :param client: Jujupy ModelClient object
    94      :return: String name of current controller
    95      """
    96      raw = client.get_juju_output('switch', include_e=False).decode('utf-8')
    97      raw = raw.split(':')[0]
    98      return raw
    99  
   100  
   101  def parse_args(argv):
   102      """Parse all arguments."""
   103      parser = argparse.ArgumentParser(
   104          description='Test if juju drops selection of the current model '
   105          'when that model is destroyed.')
   106      add_basic_testing_arguments(parser, existing=False)
   107      return parser.parse_args(argv)
   108  
   109  
   110  def main(argv=None):
   111      args = parse_args(argv)
   112      configure_logging(args.verbose)
   113      bs_manager = BootstrapManager.from_args(args)
   114      with bs_manager.booted_context(args.upload_tools):
   115          assess_destroy_model(bs_manager.client)
   116      return 0
   117  
   118  
   119  if __name__ == '__main__':
   120      sys.exit(main())