~ubuntu-cloud-archive/ubuntu/precise/glance/folsom

« back to all changes in this revision

Viewing changes to glance/tests/functional/test_respawn.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short, Chuck Short, Soren Hansen
  • Date: 2012-09-07 12:17:46 UTC
  • mfrom: (1.1.42)
  • Revision ID: package-import@ubuntu.com-20120907121746-a4i0aewhlzb7vw31
Tags: 2012.2~rc1~20120907.129.f0bd856-0ubuntu1
[ Chuck Short ]
* New upstream version.
* drop debian/patches/fix-docs-build.patch. 
* debian/rules: Re-activate tests.
* debain/control: Add depends on python-swiftclient.
* debian/*.usptart: make glance start from runlevel 1 to runlevel
  2. (LP: #820688)

[ Soren Hansen ]
* Update debian/watch to account for symbolically named tarballs and
  use newer URL.
* New snapshot.
* Refresh disable-network-for-docs.patch
* Fix Launchpad URLs in debian/watch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
 
 
3
 
# Copyright 2012 Red Hat, Inc
4
 
#
5
 
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
6
 
#    not use this file except in compliance with the License. You may obtain
7
 
#    a copy of the License at
8
 
#
9
 
#         http://www.apache.org/licenses/LICENSE-2.0
10
 
#
11
 
#    Unless required by applicable law or agreed to in writing, software
12
 
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
 
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
 
#    License for the specific language governing permissions and limitations
15
 
#    under the License.
16
 
 
17
 
"""Functional test case for the glance-control --respawn option """
18
 
 
19
 
import httplib2
20
 
import os
21
 
import signal
22
 
import socket
23
 
import sys
24
 
import time
25
 
 
26
 
from glance.tests import functional
27
 
from glance.tests.utils import skip_if_disabled
28
 
 
29
 
 
30
 
class TestRespawn(functional.FunctionalTest):
31
 
 
32
 
    """Functional test for glance-control --respawn """
33
 
 
34
 
    def get_versions(self):
35
 
        path = "http://%s:%d" % ("127.0.0.1", self.api_port)
36
 
        http = httplib2.Http()
37
 
        response, content = http.request(path, 'GET')
38
 
        self.assertEqual(response.status, 300)
39
 
 
40
 
    def get_pid(self):
41
 
        return int(open(self.api_server.pid_file).read().strip())
42
 
 
43
 
    def kill_server(self):
44
 
        pid = self.get_pid()
45
 
        os.killpg(pid, signal.SIGKILL)
46
 
        return pid
47
 
 
48
 
    def wait_for(self, predicate):
49
 
        count = 0
50
 
        while count < 50:
51
 
            if predicate():
52
 
                break
53
 
            else:
54
 
                time.sleep(0.1)
55
 
                count += 1
56
 
        self.assertTrue(predicate())
57
 
 
58
 
    def connection_unavailable(self, type):
59
 
        try:
60
 
            self.get_versions()
61
 
            self.fail('%s server should not be respawned' % type)
62
 
        except socket.error:
63
 
            exc_value = sys.exc_info()[1]
64
 
            self.assertTrue('Connection refused' in exc_value or
65
 
                            'ECONNREFUSED' in exc_value)
66
 
 
67
 
    @skip_if_disabled
68
 
    def test_respawn(self):
69
 
        """
70
 
        We test that the '--respawn' option causes the API server
71
 
        to be respawned after death but not after a deliberate stop
72
 
        """
73
 
        self.cleanup()
74
 
        self.api_server.server_control_options += ' --respawn'
75
 
 
76
 
        # start API server, allowing glance-control to continue running
77
 
        self.start_with_retry(self.api_server,
78
 
                              'api_port',
79
 
                              3,
80
 
                              expect_launch=True,
81
 
                              expect_exit=False,
82
 
                              expect_confirmation=False,
83
 
                              **self.__dict__.copy())
84
 
 
85
 
        # ensure the service pid has been cached
86
 
        pid_cached = lambda: os.path.exists(self.api_server.pid_file)
87
 
        self.wait_for(pid_cached)
88
 
 
89
 
        # ensure glance-control has had a chance to waitpid on child
90
 
        time.sleep(1)
91
 
 
92
 
        # verify server health with version negotiation
93
 
        self.get_versions()
94
 
 
95
 
        # server is killed ungracefully
96
 
        old_pid = self.kill_server()
97
 
 
98
 
        # ... but should be respawned
99
 
 
100
 
        # wait for pid to cycle
101
 
        pid_changed = lambda: old_pid != self.get_pid()
102
 
        self.wait_for(pid_changed)
103
 
 
104
 
        # ensure API service port is re-activated
105
 
        launch_msg = self.wait_for_servers([self.api_server])
106
 
        self.assertTrue(launch_msg is None, launch_msg)
107
 
 
108
 
        # verify server health with version negotiation
109
 
        self.get_versions()
110
 
 
111
 
        # deliberately stop server, it should not be respawned
112
 
        proc_file = '/proc/%d' % self.get_pid()
113
 
        self.stop_server(self.api_server, 'API server')
114
 
 
115
 
        # ensure last server process has gone away
116
 
        process_died = lambda: not os.path.exists(proc_file)
117
 
        self.wait_for(process_died)
118
 
 
119
 
        # deliberately stopped server should not be respawned
120
 
        launch_msg = self.wait_for_servers([self.api_server], False)
121
 
        self.assertTrue(launch_msg is None, launch_msg)
122
 
 
123
 
        # ensure the server has not been respawned
124
 
        self.connection_unavailable('deliberately stopped')
125
 
 
126
 
    @skip_if_disabled
127
 
    def test_bouncing(self):
128
 
        """
129
 
        We test that the '--respawn' option doesn't cause bouncing
130
 
        API server to be respawned
131
 
        """
132
 
        self.cleanup()
133
 
        self.api_server.server_control_options += ' --respawn'
134
 
        self.api_server.default_store = 'shouldnotexist'
135
 
 
136
 
        # start API server, allowing glance-control to continue running
137
 
        self.start_with_retry(self.api_server,
138
 
                              'api_port',
139
 
                              1,
140
 
                              expect_launch=False,
141
 
                              expect_exit=False,
142
 
                              expect_confirmation=False,
143
 
                              **self.__dict__.copy())
144
 
 
145
 
        # ensure the service pid has been cached
146
 
        pid_cached = lambda: os.path.exists(self.api_server.pid_file)
147
 
        self.wait_for(pid_cached)
148
 
 
149
 
        # ensure glance-control has had a chance to waitpid on child
150
 
        time.sleep(1)
151
 
 
152
 
        # bouncing server should not be respawned
153
 
        launch_msg = self.wait_for_servers([self.api_server], False)
154
 
        self.assertTrue(launch_msg is None, launch_msg)
155
 
 
156
 
        # ensure server process has gone away
157
 
        process_died = lambda: not os.path.exists('/proc/%d' % self.get_pid())
158
 
        self.wait_for(process_died)
159
 
 
160
 
        # ensure the server has not been respawned
161
 
        self.connection_unavailable('bouncing')