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

     1  #!/usr/bin/env python
     2  """
     3  Charms have the capability to declare that they support more than
     4  one series. Previously a separate copy of the charm was required for
     5  each series. An important constraint here is that for a given charm,
     6  all of the  listed series must be for the same distro/OS; it is not
     7  allowed to offer a  single charm for Ubuntu and CentOS for example.
     8  Supported series are added to charm metadata as follows:
     9  
    10      name: mycharm
    11      summary: "Great software"
    12      description: It works
    13      series:
    14         - xenial
    15         - trusty
    16         - angsty
    17  
    18  The default series is the first in the list:
    19  
    20      juju deploy mycharm
    21  
    22  should deploy a mycharm service running on trusty.
    23  
    24  A different, non-default series may be specified:
    25  
    26      juju deploy mycharm --series xenial
    27  
    28  It is possible to force the charm to deploy using an unsupported series
    29  (so long as the underlying OS is compatible):
    30  
    31      juju deploy mycharm --series angsty --force
    32  
    33  """
    34  from __future__ import print_function
    35  
    36  import argparse
    37  from collections import namedtuple
    38  import logging
    39  import os
    40  import subprocess
    41  import sys
    42  
    43  from deploy_stack import BootstrapManager
    44  from jujucharm import (
    45      Charm,
    46      local_charm_path,
    47  )
    48  from utility import (
    49      add_basic_testing_arguments,
    50      configure_logging,
    51      JujuAssertionError,
    52      temp_dir,
    53  )
    54  from assess_heterogeneous_control import check_series
    55  
    56  
    57  __metaclass__ = type
    58  
    59  log = logging.getLogger("assess_multi_series_charms")
    60  
    61  
    62  Test = namedtuple("Test", ["series", "service", "force", "success", "machine",
    63                             "juju1x_supported"])
    64  
    65  
    66  def assess_multi_series_charms(client, devel_series):
    67      """Assess multi series charms.
    68  
    69      :param client: Juju client.
    70      :param devel_series: The series to use for new and unsupported scenarios.
    71      :type client: jujupy.ModelClient
    72      :return: None
    73      """
    74      tests = [
    75          Test(series=devel_series, service='test0', force=False, success=False,
    76               machine=None, juju1x_supported=False),
    77          Test(series=None, service='test1', force=False, success=True,
    78               machine='0', juju1x_supported=True),
    79          Test(series="trusty", service='test2', force=False, success=True,
    80               machine='1', juju1x_supported=True),
    81          Test(series="xenial", service='test3', force=False, success=True,
    82               machine='2', juju1x_supported=False),
    83          Test(series="bionic", service='test4', force=False, success=True,
    84               machine='2', juju1x_supported=False),
    85          Test(series=devel_series, service='test5', force=True, success=True,
    86               machine='3', juju1x_supported=False),
    87      ]
    88      with temp_dir() as repository:
    89          charm_name = 'dummy'
    90          charm = Charm(charm_name, 'Test charm', series=['trusty', 'xenial', 'bionic'])
    91          charm_dir = charm.to_repo_dir(repository)
    92          charm_path = local_charm_path(
    93              charm=charm_name, juju_ver=client.version, series='trusty',
    94              repository=os.path.dirname(charm_dir))
    95          for test in tests:
    96              if client.is_juju1x() and not test.juju1x_supported:
    97                  continue
    98              log.info(
    99                  "Assessing multi series charms: test: {} charm_dir:{}".format(
   100                      test, charm_path))
   101              assert_deploy(client, test, charm_path, repository=repository)
   102              if test.machine:
   103                  check_series(client, machine=test.machine, series=test.series)
   104  
   105  
   106  def assert_deploy(client, test, charm_path, repository=None):
   107      """Deploy a charm and assert a success or fail.
   108  
   109      :param client: Juju client
   110      :type client: jujupy.ModelClient
   111      :param test: Deploy test data.
   112      :type  test: Test
   113      :param charm_dir:
   114      :type charm_dir: str
   115      :param repository: Direcotry path to the repository
   116      :type repository: str
   117      :return: None
   118      """
   119      if test.success:
   120          client.deploy(charm=charm_path, series=test.series,
   121                        service=test.service, force=test.force,
   122                        repository=repository)
   123          client.wait_for_started()
   124      else:
   125          try:
   126              client.deploy(charm=charm_path, series=test.series,
   127                            service=test.service, force=test.force,
   128                            repository=repository)
   129          except subprocess.CalledProcessError:
   130              return
   131          raise JujuAssertionError('Assert deploy failed for {}'.format(test))
   132  
   133  
   134  def parse_args(argv):
   135      """Parse all arguments."""
   136      parser = argparse.ArgumentParser(
   137          description="Test multi series charm feature")
   138      add_basic_testing_arguments(parser)
   139      parser.add_argument(
   140          '--devel-series', default="yakkety",
   141          help="The series to use when testing new and unsupported scenarios.")
   142      return parser.parse_args(argv)
   143  
   144  
   145  def main(argv=None):
   146      args = parse_args(argv)
   147      configure_logging(args.verbose)
   148      bs_manager = BootstrapManager.from_args(args)
   149      with bs_manager.booted_context(args.upload_tools):
   150          assess_multi_series_charms(bs_manager.client, args.devel_series)
   151      return 0
   152  
   153  
   154  if __name__ == '__main__':
   155      sys.exit(main())