~matsubara/maas/bootimages-cli

194.2.40 by Diogo Matsubara
fix typo in import line
1
import os
226.2.2 by Diogo Matsubara
copy logs after the test run and put them somewhere auto-package-testing can find.
2
from shutil import copytree
141 by Diogo Matsubara
add test
3
from simplejson import loads
4
import sys
5
from time import sleep
149 by Diogo Matsubara
use TestCase from testools instead of unittest and improve assertions
6
from testtools import TestCase
219.2.5 by Diogo Matsubara
add assertion function checking for command return code and output
7
from testtools.matchers import Contains
194.2.65 by Diogo Matsubara
use addDetail() correctly
8
from testtools.content import Content, text_content
9
from testtools.content_type import UTF8_TEXT
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
10
import unittest
194.2.4 by Diogo Matsubara
change how CC tests are skipped
11
from unittest import skipIf, SkipTest
174.1.1 by Raphael Badin
Add juju tests.
12
import yaml
195.1.1 by Raphael Badin
Do not use arch constraint if on precise.
13
import platform
181.1.1 by Raphael Badin
Add test for mediawiki service.
14
import urllib2
225.1.1 by Diogo Matsubara
update import_pxe_files to only download precise and saucy, update DEB_PROXY_CONFIG to use SQUID_DEB_PROXY address
15
from urlparse import urlparse
215.1.24 by Raphael Badin
Review fixes.
16
import pipes
228.1.1 by Raphael Badin
Be more tolerant with missing directories.
17
import errno
194.2.82 by Diogo Matsubara
use zmq to signal to the CC that the RC tests have finished
18
import zmq
141 by Diogo Matsubara
add test
19
194.2.82 by Diogo Matsubara
use zmq to signal to the CC that the RC tests have finished
20
from utils import (
219.2.5 by Diogo Matsubara
add assertion function checking for command return code and output
21
    assertCommandReturnCode, assertStartedUpstartService,
227.1.17 by Diogo Matsubara
update how we collect logs as per rvba review to improve test readability
22
    change_logs_permissions, is_juju_core, run_command, timeout,
229.1.2 by Raphael Badin
Do not restart Avahi/DBUS if revision >= 1828.
23
    update_pxe_config, CLUSTER_CONTROLLER_IP, SQUID_DEB_PROXY_URL,
24
    HTTP_PROXY, get_maas_revision,
219.2.5 by Diogo Matsubara
add assertion function checking for command return code and output
25
    )
194.2.51 by Diogo Matsubara
review comments from rvba, move cluster test to its own file and utilities to utils.py
26
27
sys.path.insert(0, "/usr/share/maas")
28
os.environ['DJANGO_SETTINGS_MODULE'] = 'maas.settings'
29
from django.core.management import call_command
30
from django.contrib.auth.models import User
31
32
from maasserver.models.user import get_creds_tuple
194.2.52 by Diogo Matsubara
increase timeout for dhcp set up and query if bootimages are imported.
33
from maasserver.models import BootImage
204.2.13 by Diogo Matsubara
be explicit about proxies URLS, one is for squid and another for squid-deb-proxy
34
from maasserver.utils import get_local_cluster_UUID
194.2.51 by Diogo Matsubara
review comments from rvba, move cluster test to its own file and utilities to utils.py
35
from apiclient.creds import convert_tuple_to_string
141 by Diogo Matsubara
add test
36
194.2.48 by Diogo Matsubara
fix typo
37
# Environment variables that can be used to configure
188.3.1 by Raphael Badin
Use env var to configure the test.
38
# what is tested.
39
40
# Series to install on deployed nodes.
41
NODE_SERIES = os.environ.get('NODE_SERIES', 'precise')
42
43
# Whether or not the ARM nodes should be used
44
# in the test.
188.3.5 by Raphael Badin
Formatting.
45
DO_NOT_USE_ARM_NODES = bool(
46
    os.environ.get('DO_NOT_USE_ARM_NODES', False))
188.3.1 by Raphael Badin
Use env var to configure the test.
47
194.1.3 by Raphael Badin
Avoid double negation.
48
49
USE_ARM_NODES = not DO_NOT_USE_ARM_NODES
50
216.1.1 by Raphael Badin
Don't use the ARM nodes with juju-core.
51
# We cannot use the ARM nodes with juju-core because of
52
# bug 1227722.
53
if is_juju_core():
54
    USE_ARM_NODES=False
55
188.3.7 by Raphael Badin
Merge trunk.
56
# Whether or not the juju tests should be performed.
57
DO_NOT_TEST_JUJU = bool(
58
    os.environ.get('DO_NOT_TEST_JUJU', False))
59
204.2.15 by Diogo Matsubara
actually use the decorator syntax and makes things more readable
60
# Whether or not set the http proxy. Currently only working on raring
61
DO_NOT_SET_PROXY = bool("raring" not in platform.linux_distribution())
62
194.2.76 by Diogo Matsubara
review comments
63
# Whether or not the cluster controller nodes in different network
64
# should be used.
194.2.1 by Diogo Matsubara
enable cluster controller nodes and add experimental test to use the CC
65
USE_CC_NODES = bool(os.environ.get('USE_CC_NODES', False))
188.3.1 by Raphael Badin
Use env var to configure the test.
66
185.1.1 by Raphael Badin
Fix MAAS_URL.
67
MAAS_URL = "http://192.168.21.5/MAAS"
224.1.1 by Diogo Matsubara
update tests to use new lab network addresses
68
USER_DATA_URL = "http://10.98.3.59/MAAS/metadata/enlist/latest/user-data"
141 by Diogo Matsubara
add test
69
ADMIN_USER = "admin"
70
PASSWORD = "test"
71
POWER_USER = "root"
72
POWER_PASS = "ubuntu"
73
194.2.1 by Diogo Matsubara
enable cluster controller nodes and add experimental test to use the CC
74
REGION_CONTROLLER_NODES = {
195.1.4 by Raphael Badin
Re-enable lenovo nodes.
75
    "00:E0:81:DD:D5:99" : "192.168.22.33",
76
    "00:E0:81:DD:D1:0B" : "192.168.22.34",
77
    "00:E0:81:DD:D4:11" : "192.168.22.35",
78
    "00:E0:81:D1:B1:47" : "192.168.22.36",
194.2.1 by Diogo Matsubara
enable cluster controller nodes and add experimental test to use the CC
79
    }
80
81
CLUSTER_CONTROLLER_NODES = {
82
    "00:E0:81:DD:D1:1B" : "192.168.22.37",
83
    "00:E0:81:DD:D1:2B" : "192.168.22.38",
84
    "00:E0:81:DD:D1:A3" : "192.168.22.39",
85
    "00:E0:81:DC:38:6D" : "192.168.22.40",
86
    "00:E0:81:DD:D0:FF" : "192.168.22.41",
87
    "00:E0:81:DD:D4:F9" : "192.168.22.42"
88
    }
89
90
194.2.61 by Diogo Matsubara
improve readability and remove unnecessary new line
91
LENOVO_LAB = REGION_CONTROLLER_NODES
194.2.1 by Diogo Matsubara
enable cluster controller nodes and add experimental test to use the CC
92
if USE_CC_NODES:
194.2.61 by Diogo Matsubara
improve readability and remove unnecessary new line
93
    LENOVO_LAB.update(CLUSTER_CONTROLLER_NODES)
141 by Diogo Matsubara
add test
94
95
ARM_LAB = {
96
    'fc:2f:40:d8:fb:1a': '192.168.21.50',
182.1.1 by Diogo Matsubara
Enable the 4 arm nodes again.
97
    'fc:2f:40:fa:2f:9a': '192.168.21.51',
141 by Diogo Matsubara
add test
98
    'fc:2f:40:ec:73:42': '192.168.21.52',
99
    'fc:2f:40:d5:87:ce': '192.168.21.53'
100
    }
101
226.1.1 by Diogo Matsubara
update lab dns config
102
# dnssec is now enabled by default, so disable it to avoid errors from the
103
# forwarder server.
104
# See:
105
# http://stackoverflow.com/questions/13342003/ns-got-insecure-response-parent-indicates-it-should-be-secure
141 by Diogo Matsubara
add test
106
LAB_DNS_CONFIG = """
107
options {
108
    directory "/var/cache/bind";
109
    forwarders {
224.1.1 by Diogo Matsubara
update tests to use new lab network addresses
110
    10.98.3.6;
141 by Diogo Matsubara
add test
111
    };
184.1.1 by Raphael Badin
Fix dns config.
112
    allow-query-cache {any;};
226.1.1 by Diogo Matsubara
update lab dns config
113
    dnssec-enable no;
114
    dnssec-validation no;
141 by Diogo Matsubara
add test
115
    auth-nxdomain no;    # conform to RFC1035
116
};
117
"""
118
174.1.1 by Raphael Badin
Add juju tests.
119
JUJU_CONFIG = """
120
default: maas
121
environments:
122
  maas:
123
    type: maas
124
    maas-server: '%s'
125
    maas-oauth: '%s'
126
    admin-secret: 'nothing'
127
    default-series: %s
128
"""
129
130
215.1.17 by Raphael Badin
Different config with juju-core.
131
def make_juju_config():
132
    config = JUJU_CONFIG
133
    if not is_juju_core():
134
        config = "%s%s" % (config, "    juju-origin: ppa\n")
135
    return config
136
137
177.3.1 by Raphael Badin
Improve juju-related code.
138
def setup_juju_config(server, oauth, series):
174.1.1 by Raphael Badin
Add juju tests.
139
    juju_dir = os.path.expanduser('~/.juju')
174.1.4 by Raphael Badin
Split script.
140
    try:
141
        os.mkdir(juju_dir)
142
    except OSError:
143
        pass
215.1.17 by Raphael Badin
Different config with juju-core.
144
    config_content = make_juju_config() % (server, oauth, series)
174.1.1 by Raphael Badin
Add juju tests.
145
    juju_configfile = os.path.join(juju_dir, 'environments.yaml')
174.1.3 by Raphael Badin
Fix config writing.
146
    juju_configfile_fd = open(juju_configfile, 'w')
147
    juju_configfile_fd.write(config_content)
174.1.1 by Raphael Badin
Add juju tests.
148
149
150
def get_token_str():
151
    admin = User.objects.get(username=ADMIN_USER)
152
    token = admin.tokens.all()[0]
153
    return convert_tuple_to_string(get_creds_tuple(token))
154
141 by Diogo Matsubara
add test
155
174.1.4 by Raphael Badin
Split script.
156
def setup_ssh():
157
    home_dir = os.path.expanduser('~/')
158
    ssh_dir = os.path.join(home_dir, '.ssh')
159
    # Setup ssh keys.
160
    ssh_key = os.path.join(ssh_dir, 'id_rsa')
161
    if not os.path.exists(ssh_key):
162
        try:
163
            os.mkdir(ssh_dir)
164
        except OSError:
165
            pass
194.2.5 by Diogo Matsubara
move self._run_command outside the class as a helper function
166
        run_command(['ssh-keygen', '-t', 'rsa', '-N', '', '-f', ssh_key])
174.1.4 by Raphael Badin
Split script.
167
    # Setup ssh config.
168
    ssh_config = os.path.join(ssh_dir, 'config')
169
    with open(ssh_config, 'w') as f:
170
        f.write('StrictHostKeyChecking no')
171
172
173
def setup_local_dns():
174
    content = open('/etc/resolv.conf').read()
175
    content = 'nameserver 127.0.0.1\n' + content
176
    with open('/etc/resolv.conf', 'w') as f:
177
        f.write(content)
178
174.1.8 by Raphael Badin
Fix style.
179
180
DEB_PROXY_CONFIG = """
225.1.1 by Diogo Matsubara
update import_pxe_files to only download precise and saucy, update DEB_PROXY_CONFIG to use SQUID_DEB_PROXY address
181
cache_peer %s parent %s 0 no-query no-digest
174.1.8 by Raphael Badin
Fix style.
182
never_direct allow all
225.1.1 by Diogo Matsubara
update import_pxe_files to only download precise and saucy, update DEB_PROXY_CONFIG to use SQUID_DEB_PROXY address
183
""" % (urlparse(SQUID_DEB_PROXY_URL).hostname,
184
       urlparse(SQUID_DEB_PROXY_URL).port)
174.1.8 by Raphael Badin
Fix style.
185
225.1.1 by Diogo Matsubara
update import_pxe_files to only download precise and saucy, update DEB_PROXY_CONFIG to use SQUID_DEB_PROXY address
186
# Configure the region proxy to use the proxy.
174.1.4 by Raphael Badin
Split script.
187
def setup_deb_proxy():
188
    config = '/etc/squid-deb-proxy/squid-deb-proxy.conf'
189
    content = open(config).read()
174.1.8 by Raphael Badin
Fix style.
190
    content = content + DEB_PROXY_CONFIG
174.1.4 by Raphael Badin
Split script.
191
    with open(config, 'w') as f:
192
        f.write(content)
194.2.5 by Diogo Matsubara
move self._run_command outside the class as a helper function
193
    run_command(['sudo', 'service', 'squid-deb-proxy', 'restart'])
194
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
195
tests_order = [
196
    "test_create_admin",
215.1.1 by Raphael Badin
juju-core compatibility fixes. Restart dbus and avahi before restarting MAAS.
197
    "test_restart_dbus_avahi",
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
198
    "test_update_maas_url",
227.1.11 by Diogo Matsubara
add the test to the list
199
    "test_restart_provisioning_server",
209.1.1 by Raphael Badin
Add check to assert that services are running.
200
    "test_check_initial_services",
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
201
    "test_update_pxe_config",
202
    "test_import_pxe_files",
227.1.16 by Diogo Matsubara
enable arm preseed update test and remove ipmi debugging patch
203
    "test_update_preseed_arm",
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
204
    "test_login_api",
204.2.1 by Diogo Matsubara
add test_set_http_proxy() to set the http_proxy using the maas-cli
205
    "test_set_http_proxy",
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
206
    "test_cluster_connected",
207
    "test_set_up_dhcp_region",
209.1.1 by Raphael Badin
Add check to assert that services are running.
208
    "test_check_dhcp_service",
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
209
    "test_set_up_dhcp_cluster",
210
    "test_update_dns_config",
211
    "test_boot_nodes_enlist",
212
    "test_check_nodes_declared",
213
    "test_set_nodes_ipmi_config",
214
    "test_commission_nodes",
215
    "test_check_nodes_ready",
203.1.1 by Diogo Matsubara
fix tag tests order
216
    "test_apply_tag_to_all_nodes",
217
    "test_check_tag_applied_to_all_nodes",
215.1.1 by Raphael Badin
juju-core compatibility fixes. Restart dbus and avahi before restarting MAAS.
218
    "test_configure_juju",
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
219
    "test_juju_bootstrap",
220
    "test_juju_setup",
221
    "test_juju_deploy_mediawiki",
222
    "test_mediawiki_homepage",
223
    "test_juju_add_unit_mediawiki"
224
]
225
226
194.2.71 by Diogo Matsubara
define the sorting function instead of using lambda
227
def sorting_method(ignored, first_test, second_test):
228
    return tests_order.index(first_test) - tests_order.index(second_test)
229
230
231
unittest.TestLoader.sortTestMethodsUsing = sorting_method
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
232
194.2.5 by Diogo Matsubara
move self._run_command outside the class as a helper function
233
141 by Diogo Matsubara
add test
234
class TestMAASIntegration(TestCase):
235
188.2.4 by Raphael Badin
Add option to disable ARM nodes.
236
    def get_node_count(self):
237
        """The number of available nodes."""
238
        count = len(LENOVO_LAB)
194.1.3 by Raphael Badin
Avoid double negation.
239
        if USE_ARM_NODES:
188.2.4 by Raphael Badin
Add option to disable ARM nodes.
240
            count += len(ARM_LAB)
241
        return count
242
141 by Diogo Matsubara
add test
243
    def _run_maas_cli(self, args):
219.2.10 by Diogo Matsubara
fix run_maas_cli return values
244
        retcode, output, err = run_command(["maas-cli", "maas"] + args)
245
        self.addDetail('retcode for maas-cli maas %s' %
246
            str(args), text_content(str(retcode)))
247
        self.addDetail('stdout for maas-cli maas %s' %
248
            str(args), text_content(str(output)))
249
        self.addDetail('stderr for maas-cli maas %s' %
250
            str(args), text_content(str(err)))
251
        return (output, err)
141 by Diogo Matsubara
add test
252
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
253
    def test_create_admin(self):
141 by Diogo Matsubara
add test
254
        """Run maas createsuperuser."""
255
        cmd_output = call_command(
256
            "createadmin", username=ADMIN_USER, password=PASSWORD,
257
            email="example@canonical.com", noinput=True)
258
        # No output, means admin user was created successfully.
259
        self.assertEqual(cmd_output, None)
260
229.1.6 by Raphael Badin
Use skipIf.
261
    # Since revision 1828, MAAS doesn't use avahi/dbus anymore so
262
    # we do not need to restart these daemons.
263
    @unittest.skipIf(
264
        get_maas_revision() >= 1828, "Avahi/DBUS are not used anymore")
215.1.1 by Raphael Badin
juju-core compatibility fixes. Restart dbus and avahi before restarting MAAS.
265
    def test_restart_dbus_avahi(self):
219.2.5 by Diogo Matsubara
add assertion function checking for command return code and output
266
        cmd = ["service", "dbus", "restart"]
267
        expected_output = 'dbus start/running'
229.1.4 by Raphael Badin
Use implicit value for 'expected_retcode'.
268
        assertCommandReturnCode(self, cmd, expected_output)
219.2.5 by Diogo Matsubara
add assertion function checking for command return code and output
269
        cmd = ["service", "avahi-daemon", "restart"]
270
        expected_output = 'avahi-daemon start/running'
229.1.4 by Raphael Badin
Use implicit value for 'expected_retcode'.
271
        assertCommandReturnCode(self, cmd, expected_output)
215.1.1 by Raphael Badin
juju-core compatibility fixes. Restart dbus and avahi before restarting MAAS.
272
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
273
    def test_update_maas_url(self):
141 by Diogo Matsubara
add test
274
        #XXX: matsubara For some reason using a debconf file to set the
275
        # initial value of DEFAULT_MAAS_URL is not working.
276
        maas_fd = open("/etc/maas/maas_local_settings.py" , "r+")
277
        maas_file = maas_fd.read()
278
        maas_file = maas_file.replace(
227.1.8 by Diogo Matsubara
change DEFAULT_MAAS_URL
279
            'DEFAULT_MAAS_URL = "http://10.0.2.15/MAAS"',
141 by Diogo Matsubara
add test
280
            'DEFAULT_MAAS_URL = "http://192.168.21.5/MAAS"')
281
        maas_fd.seek(0)
282
        maas_fd.write(maas_file)
283
        maas_fd.close()
219.2.5 by Diogo Matsubara
add assertion function checking for command return code and output
284
        cmd = ["service", "apache2", "restart"]
285
        expected_output = ' * Restarting web server apache2'
219.2.7 by Diogo Matsubara
fix assertCommandReturnCode callsite
286
        assertCommandReturnCode(self, cmd, expected_output)
141 by Diogo Matsubara
add test
287
227.1.10 by Diogo Matsubara
restart pserv so it'll listen on all interfaces
288
    def test_restart_provisioning_server(self):
289
        # Restart the provisioning server as MAAS is installed before the
290
        # network is properly configured, which makes pserv listen only in
291
        # the 10.0.2.15 interface.
292
        cmd = ["service", "maas-pserv", "restart"]
293
        expected_output = 'maas-pserv start/running'
294
        assertCommandReturnCode(self, cmd, expected_output)
295
209.1.1 by Raphael Badin
Add check to assert that services are running.
296
    def test_check_initial_services(self):
297
        assertStartedUpstartService(
298
            self, 'maas-cluster-celery',
299
            '/var/log/upstart/maas-cluster-celery.log')
300
        assertStartedUpstartService(
301
            self, 'maas-region-celery',
302
            '/var/log/upstart/maas-region-celery.log')
303
        assertStartedUpstartService(self, 'maas-txlongpoll')
304
        assertStartedUpstartService(
305
            self, 'maas-pserv', '/var/log/maas/pserv.log')
306
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
307
    def test_update_pxe_config(self):
218.1.4 by Raphael Badin
Restore update_pxe_config
308
        update_pxe_config()
141 by Diogo Matsubara
add test
309
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
310
    def test_import_pxe_files(self):
219.2.8 by Diogo Matsubara
allow callers of assertCommandReturnCode to change the env and use the new env to run the command
311
        env = os.environ.copy()
312
        env['http_proxy'] = HTTP_PROXY
219.2.5 by Diogo Matsubara
add assertion function checking for command return code and output
313
        cmd = ['maas-import-pxe-files']
314
        expected_output = 'Downloading to temporary location'
219.2.8 by Diogo Matsubara
allow callers of assertCommandReturnCode to change the env and use the new env to run the command
315
        assertCommandReturnCode(self, cmd, expected_output, env=env)
141 by Diogo Matsubara
add test
316
227.1.16 by Diogo Matsubara
enable arm preseed update test and remove ipmi debugging patch
317
    def test_update_preseed_arm(self):
318
        #XXX: matsubara add workaround to boot arm nodes.
319
        try:
320
            # Try the old location first, the one used before the templates
321
            # were moved to /etc/maas/.
322
            userdata_fd = open("/usr/share/maas/preseeds/enlist_userdata", "rb+")
323
        except IOError:
324
            userdata_fd = open("/etc/maas/preseeds/enlist_userdata", "rb+")
325
        userdata = userdata_fd.read()
326
        userdata += '\napt_sources:\n - source: "deb http://ports.ubuntu.com/ubuntu-ports precise-proposed main"'
327
        userdata_fd.seek(0)
328
        userdata_fd.write(userdata)
329
        userdata_fd.close()
141 by Diogo Matsubara
add test
330
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
331
    def test_login_api(self):
174.1.1 by Raphael Badin
Add juju tests.
332
        token_str = get_token_str()
159 by Diogo Matsubara
change test name scheme so we can get better reporting when they're running
333
        api_url = MAAS_URL + "/api/1.0/"
219.2.5 by Diogo Matsubara
add assertion function checking for command return code and output
334
        cmd = ["maas-cli", "login", "maas", api_url, token_str]
335
        expected_output = "\nYou are now logged in to the MAAS server"
336
        assertCommandReturnCode(self, cmd, expected_output)
194.2.43 by Diogo Matsubara
set a timeout for set_up_dhcp
337
204.2.16 by Diogo Matsubara
invalid syntax
338
    @skipIf(DO_NOT_SET_PROXY, "Not testing proxy.")
204.2.1 by Diogo Matsubara
add test_set_http_proxy() to set the http_proxy using the maas-cli
339
    def test_set_http_proxy(self):
340
        output, err = self._run_maas_cli([
204.2.2 by Diogo Matsubara
use set-config properly
341
            "maas", "set-config", "name=http_proxy",
204.2.13 by Diogo Matsubara
be explicit about proxies URLS, one is for squid and another for squid-deb-proxy
342
            "value=%s" % SQUID_DEB_PROXY_URL])
204.2.1 by Diogo Matsubara
add test_set_http_proxy() to set the http_proxy using the maas-cli
343
        self.assertThat(output, Contains("OK"))
344
        output, err = self._run_maas_cli([
345
            "maas", "get-config", "name=http_proxy"])
204.2.13 by Diogo Matsubara
be explicit about proxies URLS, one is for squid and another for squid-deb-proxy
346
        self.assertThat(output, Contains(SQUID_DEB_PROXY_URL))
204.2.6 by Diogo Matsubara
allow anonymous access to them etadata server
347
204.2.4 by Diogo Matsubara
check the user data passed on to nodes have the apt-proxy set
348
        # Check that the user-data passed on to nodes have the proxy address.
204.2.17 by Diogo Matsubara
use a variable for the user data URL
349
        output = urllib2.urlopen(USER_DATA_URL).read()
204.2.4 by Diogo Matsubara
check the user data passed on to nodes have the apt-proxy set
350
        self.assertThat(output, Contains(
204.2.13 by Diogo Matsubara
be explicit about proxies URLS, one is for squid and another for squid-deb-proxy
351
            "apt_proxy: %s" % SQUID_DEB_PROXY_URL))
204.2.1 by Diogo Matsubara
add test_set_http_proxy() to set the http_proxy using the maas-cli
352
198.1.3 by Raphael Badin
Fix cluster waiting code.
353
    def get_master_ng_uuid(self):
354
        output, err = self._run_maas_cli(["node-groups", "list"])
355
        node_groups = loads(output)
356
        master_nodegroup = node_groups[0]
198.1.5 by Raphael Badin
Fix typo.
357
        return master_nodegroup['uuid']
198.1.3 by Raphael Badin
Fix cluster waiting code.
358
194.2.43 by Diogo Matsubara
set a timeout for set_up_dhcp
359
    @timeout(5*60)
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
360
    def test_cluster_connected(self):
198.1.1 by Raphael Badin
Wait for cluster to connect.
361
        # The master cluster is connected and changed the uuid field of the
362
        # nodegroup object from 'master' to its UUID.
198.1.3 by Raphael Badin
Fix cluster waiting code.
363
        name = self.get_master_ng_uuid()
364
        while name == 'master':
198.1.1 by Raphael Badin
Wait for cluster to connect.
365
            sleep(10)
198.1.3 by Raphael Badin
Fix cluster waiting code.
366
            name = self.get_master_ng_uuid()
198.1.1 by Raphael Badin
Wait for cluster to connect.
367
200.1.3 by Diogo Matsubara
separate workaround from test code
368
    def _update_dhcpd_apparmor_profile(self):
369
        """Workaround for raring due to bug 1107686."""
370
        dhcpd_fd = open("/etc/apparmor.d/usr.sbin.dhcpd", "r+")
371
        dhcpd_file = dhcpd_fd.read()
372
        dhcpd_file = dhcpd_file.replace(
373
            'network packet packet,',
374
            'network packet packet,\n  network packet raw,')
375
        dhcpd_fd.seek(0)
376
        dhcpd_fd.write(dhcpd_file)
377
        dhcpd_fd.close()
219.2.5 by Diogo Matsubara
add assertion function checking for command return code and output
378
        cmd = ["service", "apparmor", "reload"]
379
        expected_output = '* Reloading AppArmor profiles'
380
        assertCommandReturnCode(self, cmd, expected_output)
200.1.3 by Diogo Matsubara
separate workaround from test code
381
194.2.53 by Diogo Matsubara
use matchesStructure.byEquality and refactor dhcp config
382
    def _set_up_dhcp(self, uuid, dhcp_config):
194.2.55 by Diogo Matsubara
forgot to use .items() in dict
383
        dhcp_cli_args = [
384
            "%s=%s" % (key, value) for key, value in dhcp_config.items()]
194.2.58 by Diogo Matsubara
fix how the dhcp config is checked
385
        maas_dhcp_cmd = [
386
            "node-group-interface", "update", uuid, "eth1" ] + dhcp_cli_args
194.2.53 by Diogo Matsubara
use matchesStructure.byEquality and refactor dhcp config
387
        output, err = self._run_maas_cli(maas_dhcp_cmd)
388
        node_group = loads(output)
194.2.58 by Diogo Matsubara
fix how the dhcp config is checked
389
        # The JSON object returned by MAAS doesn't include the router_ip
390
        # address, so let's remove it from the dhcp_config before comparing.
391
        dhcp_config.pop('router_ip')
194.2.57 by Diogo Matsubara
use assertEquals instead of matchesStructure
392
        self.assertEquals(node_group, dhcp_config)
194.2.53 by Diogo Matsubara
use matchesStructure.byEquality and refactor dhcp config
393
194.2.52 by Diogo Matsubara
increase timeout for dhcp set up and query if bootimages are imported.
394
    @timeout(5*60)
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
395
    def test_set_up_dhcp_region(self):
207.2.3 by Diogo Matsubara
fix how we check for the distro running the tests
396
        release = platform.linux_distribution()[2]
397
        if release in ('quantal', 'raring'):
200.1.3 by Diogo Matsubara
separate workaround from test code
398
            self._update_dhcpd_apparmor_profile()
200.1.1 by Diogo Matsubara
workaround for bug 1107686
399
194.2.59 by Diogo Matsubara
fix syntax error and use get_local_cluster_UUID from maas instead of parsing the cluster file directly
400
        region_uuid = get_local_cluster_UUID()
194.2.30 by Diogo Matsubara
get the region uuid directly from maas. don't rely on ordered results from maas-cli
401
145 by Diogo Matsubara
update how dhcp is configured and min number of nodes to wait for
402
        output, err = self._run_maas_cli(["node-groups", "list"])
403
        node_groups = loads(output)
194.2.30 by Diogo Matsubara
get the region uuid directly from maas. don't rely on ordered results from maas-cli
404
405
        ng_uuids = [ng['uuid'] for ng in node_groups]
406
        self.assertIn(region_uuid, ng_uuids)
407
194.2.53 by Diogo Matsubara
use matchesStructure.byEquality and refactor dhcp config
408
        region_dhcp_config = {
409
            "ip": "192.168.21.5",
410
            "interface": "eth1",
411
            "subnet_mask": "255.255.255.0",
412
            "broadcast_ip": "192.168.21.255",
413
            "router_ip": "192.168.21.1",
194.2.60 by Diogo Matsubara
fix dhcp config dict
414
            "management": 2,
194.2.53 by Diogo Matsubara
use matchesStructure.byEquality and refactor dhcp config
415
            "ip_range_low": "192.168.21.10",
229.1.9 by Raphael Badin
Fix DHCP range.
416
            "ip_range_high": "192.168.21.200"}
194.2.53 by Diogo Matsubara
use matchesStructure.byEquality and refactor dhcp config
417
418
        self._set_up_dhcp(region_uuid, region_dhcp_config)
419
153 by Diogo Matsubara
fix assertion for dhcp setup
420
        # Wait for the task to complete and create the dhcpd.conf file.
141 by Diogo Matsubara
add test
421
        while os.path.exists("/etc/maas/dhcpd.conf") is False:
194.2.65 by Diogo Matsubara
use addDetail() correctly
422
            self.addDetail(
423
                "Waiting task create dhcpd.conf file.",
424
                Content(UTF8_TEXT, lambda:
194.2.72 by Diogo Matsubara
fix log name
425
                    open("/var/log/maas/celery-region.log", 'r').readlines()))
141 by Diogo Matsubara
add test
426
            sleep(2)
194.2.62 by Diogo Matsubara
separate dhcp set up for the region and the cluster
427
209.1.1 by Raphael Badin
Add check to assert that services are running.
428
    def test_check_dhcp_service(self):
429
        assertStartedUpstartService(
430
            self, 'maas-dhcp-server',
431
            '/var/log/upstart/maas-dhcp-server.log')
432
194.2.62 by Diogo Matsubara
separate dhcp set up for the region and the cluster
433
    @skipIf(not USE_CC_NODES, "Not testing cluster controller")
194.2.81 by Diogo Matsubara
decrease timeout for set_up_dhcp_cluster
434
    @timeout(5*60)
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
435
    def test_set_up_dhcp_cluster(self):
194.2.62 by Diogo Matsubara
separate dhcp set up for the region and the cluster
436
        output, err = self._run_maas_cli(["node-groups", "list"])
437
        node_groups = loads(output)
438
        # Wait until we have two node_group since the cluster controller
439
        # might take some time to finish its configuration and contact the
440
        # region controller.
441
        while not len(node_groups) == 2:
442
            output, err = self._run_maas_cli(["node-groups", "list"])
443
            node_groups = loads(output)
444
445
        for ng in node_groups:
446
            if ng['uuid'] != get_local_cluster_UUID():
447
                cluster_uuid = ng['uuid']
448
                break
449
        # Configure the cluster controller DHCP server.
450
        cluster_dhcp_config = {
451
            "ip": "192.168.20.5",
452
            "interface": "eth1",
453
            "subnet_mask": "255.255.255.0",
454
            "broadcast_ip": "192.168.20.255",
455
            "router_ip": "192.168.20.1",
456
            "management": 2,
457
            "ip_range_low": "192.168.20.10",
458
            "ip_range_high": "192.168.20.30",
459
            }
460
        self._set_up_dhcp(cluster_uuid, cluster_dhcp_config)
461
462
        # Accept the cluster controller into the MAAS server.
463
        output, err = self._run_maas_cli([
464
            "node-groups", "accept", "uuid=%s" % cluster_uuid])
465
        self.assertThat(
466
            output, Contains("Nodegroup(s) accepted."))
467
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
468
    def test_update_dns_config(self):
159 by Diogo Matsubara
change test name scheme so we can get better reporting when they're running
469
        #XXX: matsubara Could be asked by maas-dns package and configurable
470
        # through debconf seed file.
471
        dns_config = open("/etc/bind/named.conf.options", 'w')
472
        dns_config.write(LAB_DNS_CONFIG)
473
        dns_config.close()
219.2.5 by Diogo Matsubara
add assertion function checking for command return code and output
474
        cmd = ["service", "bind9", "restart"]
475
        expected_output = '* Starting domain name service... bind9'
476
        assertCommandReturnCode(self, cmd, expected_output)
159 by Diogo Matsubara
change test name scheme so we can get better reporting when they're running
477
141 by Diogo Matsubara
add test
478
    def power_on(self, ip, user, password):
219.2.5 by Diogo Matsubara
add assertion function checking for command return code and output
479
        cmd =  ["ipmipower", "-h", ip, "-u", user, "-p", password, "--on"]
480
        expected_output = "%s: ok" % ip
481
        assertCommandReturnCode(self, cmd, expected_output)
141 by Diogo Matsubara
add test
482
483
    def power_off(self, ip, user, password):
219.2.5 by Diogo Matsubara
add assertion function checking for command return code and output
484
        cmd =  ["ipmipower", "-h", ip, "-u", user, "-p", password, "--off"]
485
        expected_output = "%s: ok" % ip
486
        assertCommandReturnCode(self, cmd, expected_output)
141 by Diogo Matsubara
add test
487
159 by Diogo Matsubara
change test name scheme so we can get better reporting when they're running
488
    def _boot_nodes(self):
141 by Diogo Matsubara
add test
489
        # Run ipmipower to boot up nodes.
490
        for ipmi_address in LENOVO_LAB.values():
491
            self.power_off(ipmi_address, POWER_USER, POWER_PASS)
492
            self.power_on(ipmi_address, POWER_USER, POWER_PASS)
194.1.3 by Raphael Badin
Avoid double negation.
493
        if USE_ARM_NODES:
188.2.4 by Raphael Badin
Add option to disable ARM nodes.
494
            for ipmi_address in ARM_LAB.values():
495
                self.power_off(ipmi_address, 'admin', 'admin')
496
                self.power_on(ipmi_address, 'admin', 'admin')
141 by Diogo Matsubara
add test
497
194.2.25 by Diogo Matsubara
add a delay to boot the nodes, so the cluster controller can finish importing pxe files
498
    # XXX: matsubara bug=1108319
499
    # revert the timeout back to the original value once bug is fixed.
500
    #@timeout(3*60)
194.2.49 by Diogo Matsubara
reduce wait during boot nodes for enlistment
501
    @timeout(8*60)
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
502
    def test_boot_nodes_enlist(self):
194.2.21 by Diogo Matsubara
add a test (that will likely fail) that waits for the cluster controller to import pxe files before booting the nodes.
503
        if USE_CC_NODES:
194.2.25 by Diogo Matsubara
add a delay to boot the nodes, so the cluster controller can finish importing pxe files
504
            # XXX: matsubara bug=1108319
505
            #  The maas-cli doesn't have a way to tell if cluster controllers
194.2.52 by Diogo Matsubara
increase timeout for dhcp set up and query if bootimages are imported.
506
            #  are missing the boot image.
507
            while not BootImage.objects.all().exists():
194.2.63 by Diogo Matsubara
addDetail() to tests that might timeout
508
                self.addDetail(
194.2.65 by Diogo Matsubara
use addDetail() correctly
509
                    "Waiting cluster controller import boot images.",
510
                    text_content(BootImage.objects.all()))
194.2.52 by Diogo Matsubara
increase timeout for dhcp set up and query if bootimages are imported.
511
                sleep(10)
159 by Diogo Matsubara
change test name scheme so we can get better reporting when they're running
512
        self._boot_nodes()
513
188.2.4 by Raphael Badin
Add option to disable ARM nodes.
514
    def _wait_nodes(self, status, min_node=None):
515
        """Wait for `min_node` nodes with status `status`."""
516
        if min_node is None:
517
            min_node = self.get_node_count()
141 by Diogo Matsubara
add test
518
        # XXX: matsubara Can't filter by status.
519
        output, err = self._run_maas_cli(["nodes", "list"])
520
        node_list = loads(output)
521
        filtered_list = [
522
            node for node in node_list if node['status'] == status]
523
        while not len(filtered_list) == min_node:
524
            sleep(5)
525
            output, err = self._run_maas_cli(["nodes", "list"])
526
            node_list = loads(output)
527
            filtered_list = [
528
                node for node in node_list if node['status'] == status]
529
194.2.78 by Diogo Matsubara
increase timeout for check_nodes_declared test
530
    @timeout(7*60)
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
531
    def test_check_nodes_declared(self):
141 by Diogo Matsubara
add test
532
        self._wait_nodes(0)
533
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
534
    def test_set_nodes_ipmi_config(self):
141 by Diogo Matsubara
add test
535
        """Set IPMI configuration for each node."""
536
        all_nodes = {}
537
        all_nodes.update(LENOVO_LAB)
538
        all_nodes.update(ARM_LAB)
539
        for mac in all_nodes.keys():
540
            # run maas-cli command to search node by mac and return system_id
541
            out, err = self._run_maas_cli(
542
                ["nodes", "list", "mac_address=%s" % mac])
543
            node_list = loads(out)
544
            for node in node_list:
545
                if ARM_LAB.has_key(mac):
546
                    power_user = power_pass = 'admin'
547
                else:
548
                    power_user = POWER_USER
549
                    power_pass = POWER_PASS
174.1.1 by Raphael Badin
Add juju tests.
550
                self._run_maas_cli(
141 by Diogo Matsubara
add test
551
                    ["node", "update", node['system_id'], "power_type=ipmi",
552
                    "power_parameters_power_address=%s " % all_nodes[mac],
553
                    "power_parameters_power_user=%s" % power_user,
554
                    "power_parameters_power_pass=%s" % power_pass])
555
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
556
    def test_commission_nodes(self):
141 by Diogo Matsubara
add test
557
        # Use maas-cli to accept all nodes.
148 by Diogo Matsubara
add asserts
558
        output, err = self._run_maas_cli(["nodes","accept-all"])
559
        for node in loads(output):
163 by Diogo Matsubara
fix assertion after commission
560
            self.assertEqual(node['status'], 1)
141 by Diogo Matsubara
add test
561
174.1.10 by Raphael Badin
Increase timeout.
562
    @timeout(10*60)
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
563
    def test_check_nodes_ready(self):
159 by Diogo Matsubara
change test name scheme so we can get better reporting when they're running
564
        self._wait_nodes(4)
174.1.1 by Raphael Badin
Add juju tests.
565
203.1.1 by Diogo Matsubara
fix tag tests order
566
    def test_apply_tag_to_all_nodes(self):
201.1.1 by Martin Packman
Add coverage for using maas-tags to integration tests
567
        # Use maas-cli to set a tag on all nodes.
201.1.6 by Martin Packman
Re-rename tag to avoid tickling another bug in the url routing
568
        output, err = self._run_maas_cli(["tags", "new", "name=all",
201.1.7 by Martin Packman
Tag definition to match all nodes should use true() function not look for node true
569
            "definition=true()", "comment=A tag present on all nodes"])
201.1.1 by Martin Packman
Add coverage for using maas-tags to integration tests
570
        tag = loads(output)
201.1.6 by Martin Packman
Re-rename tag to avoid tickling another bug in the url routing
571
        self.assertEqual(tag['name'], "all")
201.1.4 by Martin Packman
Add test that waits for tag to be applied to all nodes
572
573
    @timeout(10*60)
203.1.1 by Diogo Matsubara
fix tag tests order
574
    def test_check_tag_applied_to_all_nodes(self):
201.1.4 by Martin Packman
Add test that waits for tag to be applied to all nodes
575
        # Wait for all nodes to have new tag applied.
576
        expected_node_count = self.get_node_count()
577
        while True:
201.1.6 by Martin Packman
Re-rename tag to avoid tickling another bug in the url routing
578
            output, err = self._run_maas_cli(["tag", "nodes", "all"])
201.1.4 by Martin Packman
Add test that waits for tag to be applied to all nodes
579
            nodes = loads(output)
580
            if len(nodes) == expected_node_count:
581
                break
582
            sleep(5)
201.1.1 by Martin Packman
Add coverage for using maas-tags to integration tests
583
215.1.1 by Raphael Badin
juju-core compatibility fixes. Restart dbus and avahi before restarting MAAS.
584
    def _run_juju_command(self, args):
224.2.1 by Diogo Matsubara
add --debug to juju commands
585
        command = ["juju", "--debug"]
215.1.24 by Raphael Badin
Review fixes.
586
        command.extend(args)
219.2.5 by Diogo Matsubara
add assertion function checking for command return code and output
587
        retcode, output, err = run_command(command)
215.1.24 by Raphael Badin
Review fixes.
588
        command_name = " ".join(map(pipes.quote, command))
589
        self.addDetail(command_name, text_content(str(output)))
225.1.1 by Diogo Matsubara
update import_pxe_files to only download precise and saucy, update DEB_PROXY_CONFIG to use SQUID_DEB_PROXY address
590
        self.addDetail(command_name, text_content(str(err)))
215.1.1 by Raphael Badin
juju-core compatibility fixes. Restart dbus and avahi before restarting MAAS.
591
        return output
592
593
    def test_configure_juju(self):
174.1.5 by Raphael Badin
Fix tests.
594
        setup_deb_proxy()
174.1.4 by Raphael Badin
Split script.
595
        setup_ssh()
174.1.1 by Raphael Badin
Add juju tests.
596
        token_str = get_token_str()
188.1.3 by Raphael Badin
Fix comment.
597
        # Workaround bug 972829 (in juju precise).
188.1.2 by Raphael Badin
Fix url hack.
598
        server_url = MAAS_URL.replace('/MAAS', ':80/MAAS')
188.3.1 by Raphael Badin
Use env var to configure the test.
599
        setup_juju_config(server_url, token_str, series=NODE_SERIES)
174.1.4 by Raphael Badin
Split script.
600
        setup_local_dns()
601
215.1.10 by Raphael Badin
Wait for the bootstrap node to come up.
602
    def get_juju_status(self):
603
        status_output = self._run_juju_command(["status"])
215.1.24 by Raphael Badin
Review fixes.
604
        status = yaml.safe_load(status_output)
215.1.10 by Raphael Badin
Wait for the bootstrap node to come up.
605
        return status
606
188.3.10 by Raphael Badin
Fix message.
607
    @skipIf(DO_NOT_TEST_JUJU, "Not testing juju")
215.1.21 by Raphael Badin
Revert test changes.
608
    @timeout(50*60)
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
609
    def test_juju_bootstrap(self):
207.1.1 by Raphael Badin
Wait a bit.
610
        # Wait a bit to let all the nodes go down.
611
        # XXX: rvb 2013-04-23 bug=1171418
207.1.2 by Raphael Badin
Let's be sure.
612
        sleep(30)
215.1.8 by Raphael Badin
Don't pre-compute is_juju_core() value.
613
        if is_juju_core():
215.1.2 by Raphael Badin
Fix typo.
614
            command = ['bootstrap', '--upload-tools']
215.1.1 by Raphael Badin
juju-core compatibility fixes. Restart dbus and avahi before restarting MAAS.
615
        else:
215.1.2 by Raphael Badin
Fix typo.
616
            command = ['bootstrap']
215.1.9 by Raphael Badin
Do not issue juju status after bootstrap.
617
        self._run_juju_command(command)
215.1.12 by Raphael Badin
Use self._wait_machines_running in bootstrap.
618
        self._wait_machines_running(1)
177.3.1 by Raphael Badin
Improve juju-related code.
619
620
    def _wait_machines_running(self, nb_machines):
621
        """Wait until at least `nb_machines` have their agent running."""
622
        while True:
623
            status = self.get_juju_status()
215.1.12 by Raphael Badin
Use self._wait_machines_running in bootstrap.
624
            if status is not None:
625
                machines = status['machines'].values()
626
                running_machines = [
627
                    machine for machine in machines
215.1.14 by Raphael Badin
Cope with juju-core.
628
                    if machine.get('agent-state', '') in [
629
                        'running', 'started']]
215.1.12 by Raphael Badin
Use self._wait_machines_running in bootstrap.
630
                if len(running_machines) >= nb_machines:
631
                    break
177.3.1 by Raphael Badin
Improve juju-related code.
632
            sleep(20)
633
634
    def _wait_units_started(self, service, nb_units):
635
        """Wait until a service has at least `nb_units` units."""
636
        while True:
637
            status = self.get_juju_status()
182.2.3 by Raphael Badin
Fix juju status parsing.
638
            try:
639
                units = status['services'][service]['units'].values()
640
            except KeyError:
641
                units = []
177.3.1 by Raphael Badin
Improve juju-related code.
642
            started_units = [
177.3.2 by Raphael Badin
Fix juju wrappers. Add test.
643
                unit for unit in units
182.2.3 by Raphael Badin
Fix juju status parsing.
644
                if unit.get('agent-state', '') == 'started']
177.3.1 by Raphael Badin
Improve juju-related code.
645
            if len(started_units) >= nb_units:
646
                break
647
            sleep(20)
174.1.1 by Raphael Badin
Add juju tests.
648
188.3.10 by Raphael Badin
Fix message.
649
    @skipIf(DO_NOT_TEST_JUJU, "Not testing juju")
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
650
    def test_juju_setup(self):
177.3.2 by Raphael Badin
Fix juju wrappers. Add test.
651
        # Deploy mediawiki with its mysql db.
215.1.20 by Raphael Badin
Cope with juju-core specifics.
652
        # Deploy mysql.
177.3.1 by Raphael Badin
Improve juju-related code.
653
        self._run_juju_command(["deploy", "mysql"])
215.1.20 by Raphael Badin
Cope with juju-core specifics.
654
        # Deploy mediawiki.
655
        constraints = []
216.1.1 by Raphael Badin
Don't use the ARM nodes with juju-core.
656
        if USE_ARM_NODES:
215.1.20 by Raphael Badin
Cope with juju-core specifics.
657
            constraints.append("arch=arm")
658
        if not is_juju_core():
659
            constraints.append("maas-tags=all")
660
        deploy_command = ["deploy", "mediawiki"]
661
        if len(constraints) != 0:
662
            deploy_command.append("--constraints")
663
            deploy_command.append(' '.join(constraints))
664
        self._run_juju_command(deploy_command)
665
        # Bind the services together.
177.3.1 by Raphael Badin
Improve juju-related code.
666
        self._run_juju_command(["add-relation", "mediawiki:db", "mysql"])
667
        self._run_juju_command(["expose", "mediawiki"])
177.3.7 by Raphael Badin
Fix comment.
668
        # Add new unit for test 18: we run that here to
177.3.2 by Raphael Badin
Fix juju wrappers. Add test.
669
        # parallelize the installation of the new machine.
670
        self._run_juju_command(["add-unit", "mediawiki"])
671
188.3.10 by Raphael Badin
Fix message.
672
    @skipIf(DO_NOT_TEST_JUJU, "Not testing juju")
215.1.21 by Raphael Badin
Revert test changes.
673
    @timeout(40*60)
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
674
    def test_juju_deploy_mediawiki(self):
214.1.1 by jtv at canonical
Fix indentation.
675
        self._wait_machines_running(3)
676
        self._wait_units_started('mediawiki', 1)
177.3.2 by Raphael Badin
Fix juju wrappers. Add test.
677
188.3.10 by Raphael Badin
Fix message.
678
    @skipIf(DO_NOT_TEST_JUJU, "Not testing juju")
194.2.85 by Diogo Matsubara
increase timeout for test_mediawiki_homepage
679
    @timeout(6*60)
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
680
    def test_mediawiki_homepage(self):
182.2.5 by Raphael Badin
Wait a bit for mediawiki to come up.
681
        while True:
682
            status = self.get_juju_status()
683
            mediawiki_address = (
684
                status['services']['mediawiki']['units'].values(
685
                    )[0]['public-address'])
686
            self.addDetail('juju status', text_content(str(status)))
182.2.8 by Raphael Badin
Fix typo.
687
            mediawiki_url = 'http://%s/mediawiki/' % mediawiki_address
182.2.5 by Raphael Badin
Wait a bit for mediawiki to come up.
688
            opener = urllib2.build_opener()
689
            try:
690
                homepage = opener.open(mediawiki_url).read()
691
            except urllib2.URLError:
692
                pass
182.2.6 by Raphael Badin
Fix exception handling..
693
            else:
196.1.1 by Raphael Badin
Improve temporary failures detection code.
694
                temporary_failures = (
695
                    'database error' in homepage or
696
                    "LocalSettings.php not found" in homepage
697
                    )
698
                if not temporary_failures:
182.2.6 by Raphael Badin
Fix exception handling..
699
                    break
182.2.5 by Raphael Badin
Wait a bit for mediawiki to come up.
700
            sleep(15)
182.2.2 by Raphael Badin
Improve error detection.
701
181.1.1 by Raphael Badin
Add test for mediawiki service.
702
        self.assertIn("<title>Please set name of wiki</title>", homepage)
703
188.3.10 by Raphael Badin
Fix message.
704
    @skipIf(DO_NOT_TEST_JUJU, "Not testing juju")
191.1.1 by Raphael Badin
Improve timeout to cope with slow ARM nodes.
705
    @timeout(30*60)
194.2.66 by Diogo Matsubara
remove naming scheme for tests order. Add a list to keep the tests ordered and use a function to sort them according to the index
706
    def test_juju_add_unit_mediawiki(self):
177.3.2 by Raphael Badin
Fix juju wrappers. Add test.
707
        self._wait_machines_running(4)
708
        self._wait_units_started('mediawiki', 2)
194.2.1 by Diogo Matsubara
enable cluster controller nodes and add experimental test to use the CC
709
710
    @classmethod
227.1.17 by Diogo Matsubara
update how we collect logs as per rvba review to improve test readability
711
    def _collect_logs(cls, log_dirs, log_dest):
712
        """Collect logs from the test run.
713
714
        This method copies logs from the test run to a known location so
715
        auto-package-testing can copy them out of the testbed.
716
        """
717
        for log_dir in log_dirs:
718
            ignored, tail = os.path.split(log_dir)
228.1.1 by Raphael Badin
Be more tolerant with missing directories.
719
            try:
720
                copytree(log_dir, os.path.join(log_dest, tail))
721
            except OSError as e:
722
                if e.errno != errno.ENOENT:
723
                    raise
724
                # Directory does not exist: ignore and carry on.
227.1.17 by Diogo Matsubara
update how we collect logs as per rvba review to improve test readability
725
726
    @classmethod
194.2.1 by Diogo Matsubara
enable cluster controller nodes and add experimental test to use the CC
727
    def tearDownClass(cls):
226.2.2 by Diogo Matsubara
copy logs after the test run and put them somewhere auto-package-testing can find.
728
        """Collect logs and signal to the cluster tests finished."""
226.2.4 by Diogo Matsubara
fix log collector
729
        log_dest = '/var/tmp/testresults/maas-logs/'
226.2.2 by Diogo Matsubara
copy logs after the test run and put them somewhere auto-package-testing can find.
730
        log_dirs = [
226.2.4 by Diogo Matsubara
fix log collector
731
            '/var/log/maas',
732
            '/var/log/upstart',
733
            '/var/log/apache2',
734
            '/var/lib/maas/dhcp']
227.1.17 by Diogo Matsubara
update how we collect logs as per rvba review to improve test readability
735
        cls._collect_logs(log_dirs, log_dest)
736
        change_logs_permissions(log_dest)
226.2.2 by Diogo Matsubara
copy logs after the test run and put them somewhere auto-package-testing can find.
737
738
        # Signal to the cluster that the region controller tests finished.
194.2.4 by Diogo Matsubara
change how CC tests are skipped
739
        if not USE_CC_NODES:
740
            raise SkipTest("Not testing Cluster controller")
194.2.82 by Diogo Matsubara
use zmq to signal to the CC that the RC tests have finished
741
        context = zmq.Context()
742
        socket = context.socket(zmq.REQ)
743
        socket.connect('tcp://%s:5555' % CLUSTER_CONTROLLER_IP)
744
        socket.send("Region controller tests finished.")