~sinzui/juju-ci-tools/remove-jujuci-gets.

« back to all changes in this revision

Viewing changes to assess_cloud_display.py

  • Committer: Curtis Hovey
  • Date: 2016-12-06 11:22:28 UTC
  • mfrom: (1468.2.323 trunk)
  • Revision ID: curtis@canonical.com-20161206112228-qqklcieubzbbolvr
Merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
from __future__ import print_function
 
3
 
 
4
from argparse import ArgumentParser
 
5
from contextlib import contextmanager
 
6
from copy import deepcopy
 
7
from difflib import ndiff
 
8
import os
 
9
from pprint import pformat
 
10
 
 
11
import yaml
 
12
 
 
13
from jujupy import client_from_config
 
14
from utility import (
 
15
    add_arg_juju_bin,
 
16
    JujuAssertionError,
 
17
    )
 
18
 
 
19
 
 
20
def remove_display_attributes(cloud):
 
21
    """Remove the attributes added by display.
 
22
 
 
23
    The 'defined' attribute is asserted to be 'local'.
 
24
    The description attribute is asserted to be appropriate for the cloud type.
 
25
    """
 
26
    type_descriptions = {
 
27
        'openstack': 'Openstack Cloud',
 
28
        'vsphere': '',
 
29
        'manual': '',
 
30
        'maas': 'Metal As A Service',
 
31
        }
 
32
    # The lack of built-in descriptions for vsphere and manual is
 
33
    # bug #1646128.  The inability to specify descriptions interactively is
 
34
    # bug #1645783.
 
35
    defined = cloud.pop('defined')
 
36
    assert_equal(defined, 'local')
 
37
    description = cloud.pop('description')
 
38
    assert_equal(description, type_descriptions[cloud['type']])
 
39
 
 
40
 
 
41
def get_clouds(client):
 
42
    cloud_list = yaml.safe_load(client.get_juju_output(
 
43
        'clouds', '--format', 'yaml', include_e=False))
 
44
    for cloud_name, cloud in cloud_list.items():
 
45
        if cloud['defined'] == 'built-in':
 
46
            del cloud_list[cloud_name]
 
47
            continue
 
48
        remove_display_attributes(cloud)
 
49
    return cloud_list
 
50
 
 
51
 
 
52
def get_home_path(client, subpath):
 
53
    return os.path.join(client.env.juju_home, subpath)
 
54
 
 
55
 
 
56
def assert_equal(first, second):
 
57
    """If two values are not the same, raise JujuAssertionError.
 
58
 
 
59
    The text of the error is a diff of the pretty-printed values.
 
60
    """
 
61
    if first != second:
 
62
        diff = ndiff(pformat(first).splitlines(), pformat(second).splitlines())
 
63
        raise JujuAssertionError('\n' + '\n'.join(diff))
 
64
 
 
65
 
 
66
def assess_clouds(client, expected):
 
67
    """Assess how clouds behaves when only expected clouds are defined."""
 
68
    cloud_list = get_clouds(client)
 
69
    assert_equal(cloud_list, expected)
 
70
 
 
71
 
 
72
def assess_show_cloud(client, expected):
 
73
    """Assess how show-cloud behaves."""
 
74
    for cloud_name, expected_cloud in expected.items():
 
75
        actual_cloud = yaml.safe_load(client.get_juju_output(
 
76
            'show-cloud', cloud_name, '--format', 'yaml', include_e=False))
 
77
        remove_display_attributes(actual_cloud)
 
78
        assert_equal(actual_cloud, expected_cloud)
 
79
 
 
80
 
 
81
def strip_redundant_endpoints(clouds):
 
82
    no_region_endpoint = deepcopy(clouds)
 
83
    for cloud in no_region_endpoint.values():
 
84
        for region in cloud.get('regions', {}).values():
 
85
            if region['endpoint'] == cloud['endpoint']:
 
86
                region.pop('endpoint')
 
87
    return no_region_endpoint
 
88
 
 
89
 
 
90
@contextmanager
 
91
def testing(test_name):
 
92
    try:
 
93
        yield
 
94
    except Exception:
 
95
        print('{}: FAIL'.format(test_name))
 
96
        raise
 
97
    else:
 
98
        print('{}: PASS'.format(test_name))
 
99
 
 
100
 
 
101
def main():
 
102
    parser = ArgumentParser()
 
103
    parser.add_argument('clouds_file')
 
104
    add_arg_juju_bin(parser)
 
105
    args = parser.parse_args()
 
106
    client = client_from_config(None, args.juju_bin)
 
107
    with client.env.make_jes_home(client.env.juju_home, 'mytest',
 
108
                                  {}) as juju_home:
 
109
        client.env.juju_home = juju_home
 
110
        with open(get_home_path(client, 'public-clouds.yaml'), 'w') as f:
 
111
            f.write('')
 
112
        with testing('assess_clouds (no_clouds)'):
 
113
            assess_clouds(client, {})
 
114
        with open(args.clouds_file) as f:
 
115
            supplied_clouds = yaml.safe_load(f.read().decode('utf-8'))
 
116
        client.env.write_clouds(client.env.juju_home, supplied_clouds)
 
117
        no_region_endpoint = strip_redundant_endpoints(
 
118
            supplied_clouds['clouds'])
 
119
        with testing('assess_clouds'):
 
120
            assess_clouds(client, no_region_endpoint)
 
121
        with testing('assess_show_cloud'):
 
122
            assess_show_cloud(client, no_region_endpoint)
 
123
 
 
124
 
 
125
if __name__ == '__main__':
 
126
    main()