~hadware/magicicada-server/trusty-support

« back to all changes in this revision

Viewing changes to src/server/tests/test_shutdown.py

  • Committer: Facundo Batista
  • Date: 2015-08-05 13:10:02 UTC
  • Revision ID: facundo@taniquetil.com.ar-20150805131002-he7b7k704d8o7js6
First released version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2008-2015 Canonical
 
2
#
 
3
# This program is free software: you can redistribute it and/or modify
 
4
# it under the terms of the GNU Affero General Public License as
 
5
# published by the Free Software Foundation, either version 3 of the
 
6
# License, or (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU Affero General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU Affero General Public License
 
14
# along with this program. If not, see <http://www.gnu.org/licenses/>.
 
15
#
 
16
# For further info, check  http://launchpad.net/filesync-server
 
17
 
 
18
"""Test server shutdown."""
 
19
 
 
20
from twisted.trial.unittest import TestCase as TwistedTestCase
 
21
from twisted.internet import reactor, defer, error
 
22
 
 
23
from txstatsd.metrics.countermetric import CounterMetric
 
24
from txstatsd.metrics.metermetric import MeterMetric
 
25
 
 
26
from s4 import s4
 
27
from backends.filesync.data.services import make_storage_user
 
28
from backends.filesync.data.testing.testcase import StorageDALTestCase
 
29
from ubuntuone.storage.server.auth import DummyAuthProvider
 
30
from ubuntuone.storage.server.testing.testcase import StorageServerService
 
31
from ubuntuone.storageprotocol import request
 
32
from ubuntuone.storageprotocol.content_hash import content_hash_factory
 
33
from ubuntuone.storageprotocol.client import (
 
34
    StorageClientFactory, StorageClient)
 
35
 
 
36
 
 
37
class TestClient(StorageClient):
 
38
    """A simple client for tests."""
 
39
 
 
40
    def connectionMade(self):
 
41
        """Setup and call callback."""
 
42
        StorageClient.connectionMade(self)
 
43
        self.factory.connected(self)
 
44
 
 
45
 
 
46
class TestClientFactory(StorageClientFactory):
 
47
    """A test oriented protocol factory."""
 
48
    protocol = TestClient
 
49
 
 
50
 
 
51
class TestShutdown(TwistedTestCase, StorageDALTestCase):
 
52
    """Test the basic stuff."""
 
53
 
 
54
    @defer.inlineCallbacks
 
55
    def setUp(self):
 
56
        """Setup for testing."""
 
57
        # make sure we start with clean state
 
58
        yield super(TestShutdown, self).setUp()
 
59
        self.s4_site = site = s4.server.Site(s4.Root())
 
60
        self.s4_conn = reactor.listenTCP(0, site)
 
61
        # since storageusers are not automatically created, we need to create
 
62
        self.usr0 = make_storage_user(0, u"dummy", u"", 2 ** 20)
 
63
 
 
64
    @defer.inlineCallbacks
 
65
    def tearDown(self):
 
66
        """Tear down after testing."""
 
67
        yield self.s4_conn.stopListening()
 
68
        yield super(TestShutdown, self).tearDown()
 
69
 
 
70
    @defer.inlineCallbacks
 
71
    def test_shutdown_upload(self):
 
72
        """Stop and restart the server."""
 
73
        # create a server
 
74
        service = StorageServerService(
 
75
            0, "localhost", self.s4_conn.getHost().port, False,
 
76
            s4.AWS_DEFAULT_ACCESS_KEY_ID,
 
77
            s4.AWS_DEFAULT_SECRET_ACCESS_KEY,
 
78
            auth_provider_class=DummyAuthProvider,
 
79
            heartbeat_interval=0)
 
80
        yield service.startService()
 
81
 
 
82
        # create a user, connect a client
 
83
        usr0 = make_storage_user(0, u"dummy", u"", 2 ** 20)
 
84
        d = defer.Deferred()
 
85
        f = TestClientFactory()
 
86
        f.connected = d.callback
 
87
        reactor.connectTCP("localhost", service.port, f)
 
88
        client = yield d
 
89
 
 
90
        # auth, get root, create a file
 
91
        yield client.dummy_authenticate("open sesame")
 
92
        root = yield client.get_root()
 
93
        mkfile_req = yield client.make_file(request.ROOT, root, "hola")
 
94
 
 
95
        # try to upload something that will fail when sending data
 
96
        empty_hash = content_hash_factory().content_hash()
 
97
        # lose the connection if something wrong
 
98
        try:
 
99
            yield client.put_content(request.ROOT, mkfile_req.new_id,
 
100
                                     empty_hash, "fake_hash", 1234, 1000, None)
 
101
        except:
 
102
            client.transport.loseConnection()
 
103
 
 
104
        # see that the server has not protocols alive
 
105
        yield service.factory.wait_for_shutdown()
 
106
        ujobs = usr0.get_uploadjobs(node_id=mkfile_req.new_id)
 
107
        self.assertEqual(ujobs, [])
 
108
 
 
109
        yield service.stopService()
 
110
 
 
111
    @defer.inlineCallbacks
 
112
    def test_shutdown_metrics(self):
 
113
        """Stop and restart the server."""
 
114
        # create a server
 
115
        service = StorageServerService(
 
116
            0, "localhost", self.s4_conn.getHost().port, False,
 
117
            s4.AWS_DEFAULT_ACCESS_KEY_ID,
 
118
            s4.AWS_DEFAULT_SECRET_ACCESS_KEY,
 
119
            auth_provider_class=DummyAuthProvider,
 
120
            heartbeat_interval=0)
 
121
 
 
122
        yield service.startService()
 
123
 
 
124
        # ensure we employ the correct metric name.
 
125
        name = service.metrics.fully_qualify_name('server_start')
 
126
        self.assertTrue(isinstance(service.metrics._metrics[name],
 
127
                        MeterMetric))
 
128
        name = service.metrics.fully_qualify_name('services_active')
 
129
        self.assertTrue(isinstance(service.metrics._metrics[name],
 
130
                        CounterMetric))
 
131
        self.assertEquals(service.metrics._metrics[name].count(), 1)
 
132
 
 
133
        yield service.stopService()
 
134
 
 
135
    @defer.inlineCallbacks
 
136
    def test_requests_leak(self):
 
137
        """Test that the server waits for pending requests."""
 
138
        # create a server
 
139
        self.service = StorageServerService(
 
140
            0, "localhost", self.s4_conn.getHost().port, False,
 
141
            s4.AWS_DEFAULT_ACCESS_KEY_ID,
 
142
            s4.AWS_DEFAULT_SECRET_ACCESS_KEY,
 
143
            auth_provider_class=DummyAuthProvider,
 
144
            heartbeat_interval=0)
 
145
        # start it
 
146
        yield self.service.startService()
 
147
 
 
148
        make_storage_user(0, u"dummy", u"", 2 ** 20)
 
149
        client_d = defer.Deferred()
 
150
        f = TestClientFactory()
 
151
        f.connected = client_d.callback
 
152
        reactor.connectTCP("localhost", self.service.port, f)
 
153
        client = yield client_d
 
154
        # start with a client
 
155
        yield client.dummy_authenticate("open sesame")
 
156
        root_id = yield client.get_root()
 
157
        # create a bunch of files
 
158
        mk_deferreds = []
 
159
 
 
160
        def handle_conn_done(f):
 
161
            """Ignore ConnectionDone errors."""
 
162
            if f.check(error.ConnectionDone):
 
163
                return
 
164
            return f
 
165
        for i in range(10):
 
166
            mk = client.make_file(request.ROOT, root_id, "hola_%s" % i)
 
167
            mk.addErrback(handle_conn_done)
 
168
            mk_deferreds.append(mk)
 
169
        try:
 
170
            reactor.callLater(0.1, client.transport.loseConnection)
 
171
            yield defer.DeferredList(mk_deferreds)
 
172
        finally:
 
173
            self.assertTrue(self.service.factory.protocols[0].requests)
 
174
            # wait for protocol shutdown (this was hanging waiting for requests
 
175
            # to finish)
 
176
            yield self.service.factory.protocols[0].wait_for_shutdown()
 
177
            # see that the server has not protocols alive
 
178
            yield self.service.factory.wait_for_shutdown()
 
179
            # cleanup
 
180
            yield self.service.stopService()
 
181
 
 
182
    test_requests_leak.skip = """
 
183
        There seems to be a race condition on this test.
 
184
        Skipped because of https://bugs.launchpad.net/bugs/989680
 
185
    """