|
2 | 2 | Integration tests for autopilotpattern/nginx. These tests are executed
|
3 | 3 | inside a test-running container based on autopilotpattern/testing.
|
4 | 4 | """
|
| 5 | +from collections import defaultdict |
5 | 6 | import os
|
6 | 7 | from os.path import expanduser
|
7 | 8 | import random
|
8 |
| -import subprocess |
| 9 | +import re |
9 | 10 | import string
|
| 11 | +import subprocess |
10 | 12 | import sys
|
11 | 13 | import time
|
12 | 14 | import unittest
|
@@ -37,27 +39,74 @@ def setUp(self):
|
37 | 39 |
|
38 | 40 | def test_scaleup_and_down(self):
|
39 | 41 |
|
40 |
| - self.wait_for_containers(timeout=300) |
41 |
| - self.wait_for_service('backend', count=1, timeout=120) |
42 |
| - self.wait_for_service('containerpilot', count=1, timeout=120) |
43 |
| - self.wait_for_service('nginx', count=1, timeout=120) |
44 |
| - self.wait_for_service('nginx-public', count=1, timeout=120) |
| 42 | + self.instrument(self.wait_for_containers, |
| 43 | + {'backend': 1, "nginx": 1, "consul": 1}, timeout=300) |
| 44 | + self.instrument(self.wait_for_service, 'backend', count=1, timeout=120) |
| 45 | + self.instrument(self.wait_for_service, 'containerpilot', count=1, timeout=120) |
| 46 | + self.instrument(self.wait_for_service, 'nginx', count=1, timeout=120) |
| 47 | + self.instrument(self.wait_for_service, 'nginx-public', count=1, timeout=120) |
45 | 48 | # self.wait_for_service('nginx-public-ssl', count=1) # TODO
|
| 49 | + self.instrument(self.wait_for_cns) |
46 | 50 |
|
47 | 51 | self.compose_scale('backend', 2)
|
48 |
| - self.wait_for_service('backend', count=2, timeout=60) |
| 52 | + self.instrument(self.wait_for_containers, |
| 53 | + {'backend': 2, "nginx": 1, "consul": 1}, timeout=300) |
| 54 | + self.instrument(self.wait_for_service, 'backend', count=2, timeout=60) |
49 | 55 | self.compare_backends()
|
50 | 56 |
|
51 | 57 | # netsplit a backend
|
52 | 58 | self.docker_exec('backend_2', 'ifconfig eth0 down')
|
53 |
| - self.wait_for_service('backend', count=1) |
| 59 | + self.instrument(self.wait_for_service, 'backend', count=1) |
54 | 60 | self.compare_backends()
|
55 | 61 |
|
56 | 62 | # heal netsplit
|
57 | 63 | self.docker_exec('backend_2', 'ifconfig eth0 up')
|
58 |
| - self.wait_for_service('backend', count=2) |
| 64 | + self.instrument(self.wait_for_service, 'backend', count=2, timeout=60) |
59 | 65 | self.compare_backends()
|
60 | 66 |
|
| 67 | + def wait_for_containers(self, expected={}, timeout=30): |
| 68 | + """ |
| 69 | + Waits for all containers to be marked as 'Up' for all services. |
| 70 | + `expected` should be a dict of {"service_name": count}. |
| 71 | + TODO: lower this into the base class implementation. |
| 72 | + """ |
| 73 | + svc_regex = re.compile(r'^{}_(\w+)_\d+$'.format(self.project_name)) |
| 74 | + |
| 75 | + def get_service_name(container_name): |
| 76 | + return svc_regex.match(container_name).group(1) |
| 77 | + |
| 78 | + while timeout > 0: |
| 79 | + containers = self.compose_ps() |
| 80 | + found = defaultdict(int) |
| 81 | + states = [] |
| 82 | + for container in containers: |
| 83 | + service = get_service_name(container.name) |
| 84 | + found[service] = found[service] + 1 |
| 85 | + states.append(container.state == 'Up') |
| 86 | + if all(states): |
| 87 | + if not expected or found == expected: |
| 88 | + break |
| 89 | + time.sleep(1) |
| 90 | + timeout -= 1 |
| 91 | + else: |
| 92 | + raise WaitTimeoutError("Timed out waiting for containers to start.") |
| 93 | + |
| 94 | + |
| 95 | + def wait_for_cns(self, timeout=60): |
| 96 | + """ wait for CNS to catch up """ |
| 97 | + while timeout > 0: |
| 98 | + try: |
| 99 | + r = requests.get('http://{}'.format(self.nginx_cns)) # TODO: SSL |
| 100 | + if r.status_code == 200: |
| 101 | + break |
| 102 | + except requests.exceptions.ConnectionError: |
| 103 | + pass |
| 104 | + timeout -= 1 |
| 105 | + time.sleep(1) |
| 106 | + else: |
| 107 | + self.fail("nginx has not become reachable at {}" |
| 108 | + .format(self.nginx_cns)) |
| 109 | + |
61 | 110 |
|
62 | 111 | def compare_backends(self):
|
63 | 112 | expected = self.get_service_instances_from_consul('backend').sort()
|
|
0 commit comments