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())