~andrewjbeach/juju-ci-tools/make-local-patcher

« back to all changes in this revision

Viewing changes to assess_multi_series_charms.py

Merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
       - trusty
15
 
       - precise
16
 
       - wily
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 precise
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 xenial --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):
67
 
    """Assess multi series charms.
68
 
 
69
 
    :param client: Juju client.
70
 
    :type client: jujupy.EnvJujuClient
71
 
    :return: None
72
 
    """
73
 
    tests = [
74
 
        Test(series="precise", service='test0', force=False, success=False,
75
 
             machine=None, juju1x_supported=False),
76
 
        Test(series=None, service='test1', force=False, success=True,
77
 
             machine='0', juju1x_supported=True),
78
 
        Test(series="trusty", service='test2', force=False, success=True,
79
 
             machine='1', juju1x_supported=True),
80
 
        Test(series="xenial", service='test3', force=False, success=True,
81
 
             machine='2', juju1x_supported=False),
82
 
        Test(series="precise", service='test4', force=True, success=True,
83
 
             machine='3', juju1x_supported=False),
84
 
    ]
85
 
    with temp_dir() as repository:
86
 
        charm_name = 'dummy'
87
 
        charm = Charm(charm_name, 'Test charm', series=['trusty', 'xenial'])
88
 
        charm_dir = charm.to_repo_dir(repository)
89
 
        charm_path = local_charm_path(
90
 
            charm=charm_name, juju_ver=client.version, series='trusty',
91
 
            repository=os.path.dirname(charm_dir))
92
 
        for test in tests:
93
 
            if client.is_juju1x() and not test.juju1x_supported:
94
 
                continue
95
 
            log.info(
96
 
                "Assessing multi series charms: test: {} charm_dir:{}".format(
97
 
                    test, charm_path))
98
 
            assert_deploy(client, test, charm_path, repository=repository)
99
 
            if test.machine:
100
 
                check_series(client, machine=test.machine, series=test.series)
101
 
 
102
 
 
103
 
def assert_deploy(client, test, charm_path, repository=None):
104
 
    """Deploy a charm and assert a success or fail.
105
 
 
106
 
    :param client: Juju client
107
 
    :type client: jujupy.EnvJujuClient
108
 
    :param test: Deploy test data.
109
 
    :type  test: Test
110
 
    :param charm_dir:
111
 
    :type charm_dir: str
112
 
    :param repository: Direcotry path to the repository
113
 
    :type repository: str
114
 
    :return: None
115
 
    """
116
 
    if test.success:
117
 
        client.deploy(charm=charm_path, series=test.series,
118
 
                      service=test.service, force=test.force,
119
 
                      repository=repository)
120
 
        client.wait_for_started()
121
 
    else:
122
 
        try:
123
 
            client.deploy(charm=charm_path, series=test.series,
124
 
                          service=test.service, force=test.force,
125
 
                          repository=repository)
126
 
        except subprocess.CalledProcessError:
127
 
            return
128
 
        raise JujuAssertionError('Assert deploy failed for {}'.format(test))
129
 
 
130
 
 
131
 
def parse_args(argv):
132
 
    """Parse all arguments."""
133
 
    parser = argparse.ArgumentParser(
134
 
        description="Test multi series charm feature")
135
 
    add_basic_testing_arguments(parser)
136
 
    return parser.parse_args(argv)
137
 
 
138
 
 
139
 
def main(argv=None):
140
 
    args = parse_args(argv)
141
 
    configure_logging(args.verbose)
142
 
    bs_manager = BootstrapManager.from_args(args)
143
 
    with bs_manager.booted_context(args.upload_tools):
144
 
        assess_multi_series_charms(bs_manager.client)
145
 
    return 0
146
 
 
147
 
 
148
 
if __name__ == '__main__':
149
 
    sys.exit(main())