~alecu/ubuntuone-storage-protocol/timestamp-server

« back to all changes in this revision

Viewing changes to samples/easy_client.py

  • Committer: Tarmac
  • Author(s): Rodney Dawes
  • Date: 2010-11-16 15:10:48 UTC
  • mfrom: (121.1.4 use-packages)
  • Revision ID: tarmac-20101116151048-b0e20j7lorb4yhe1
Switch to using packaged mocker and ubuntuone-dev-tools
Use pyflakes with u1lint and also run pep8
Fix a lot of pylint/pyflakes/pep8 errors

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
#
5
5
# Copyright 2009 Canonical Ltd.
6
6
#
7
 
# This program is free software: you can redistribute it and/or modify it 
 
7
# This program is free software: you can redistribute it and/or modify it
8
8
# under the terms of the GNU Affero General Public License version 3,
9
9
# as published by the Free Software Foundation.
10
10
#
11
 
# This program is distributed in the hope that it will be useful, but 
12
 
# WITHOUT ANY WARRANTY; without even the implied warranties of 
13
 
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
 
11
# This program is distributed in the hope that it will be useful, but
 
12
# WITHOUT ANY WARRANTY; without even the implied warranties of
 
13
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14
14
# PURPOSE.  See the GNU Affero General Public License for more details.
15
15
#
16
16
# You should have received a copy of the GNU Affero General Public License
31
31
from ubuntuone.storageprotocol.dircontent_pb2 import \
32
32
    DirectoryContent, DIRECTORY
33
33
 
 
34
 
34
35
class NotDirectory(Exception):
35
36
    """This wasnt a directory"""
36
37
 
 
38
 
37
39
def delay_time(step):
38
40
    """generates a delay for each step"""
39
41
    return (((math.exp(step) - 1) / 10) /
40
42
            (1 + random.random()))
41
43
 
 
44
 
42
45
def retry(function):
43
46
    """This function will be retried when it raises TRY_AGAIN from the server.
44
47
    """
45
48
    def inner(self, *args, **kwargs):
46
49
        """decorated."""
 
50
 
47
51
        def do_retry(failure, step):
48
52
            """retry."""
49
53
            if failure.check(request.StorageRequestError) \
53
57
                d = defer.Deferred()
54
58
                reactor.callLater(delay_time(step), d.callback, None)
55
59
                d.addCallback(lambda _: function(self, *args, **kwargs))
56
 
                d.addErrback(do_retry, step+1)
 
60
                d.addErrback(do_retry, step + 1)
57
61
                return d
58
62
            else:
59
63
                return failure
62
66
        return d
63
67
    return inner
64
68
 
 
69
 
65
70
class EasyClient(StorageClient):
66
71
    """Simple client that calls a callback on connection."""
67
72
 
73
78
 
74
79
    def connectionMade(self):
75
80
        """Setup and call callback."""
76
 
        # pylint: disable-msg=W0201
77
81
        # pylint: disable=W0201
78
82
        StorageClient.connectionMade(self)
79
83
        self.factory.clientConnectionMade(self)
85
89
            message = query[0][1].response[0]
86
90
            return message.hash
87
91
 
88
 
        d = self.query(
89
 
                [(request.ROOT, node_id, request.UNKNOWN_HASH)]
90
 
            )
 
92
        d = self.query([(request.ROOT, node_id, request.UNKNOWN_HASH)])
91
93
        d.addCallback(_got_query)
92
94
        return d
93
95
 
119
121
            id.
120
122
            """
121
123
            d = self._get_content(parent)
 
124
 
122
125
            def is_directory(content):
123
126
                """parse dircontent to find a directory with name == name."""
124
127
                unserialized_content = DirectoryContent()
127
130
                    if entry.name == name and entry.node_type == DIRECTORY:
128
131
                        print "is directory", entry
129
132
                        return entry.node
130
 
                raise NotDirectory("name %s is not a directory"%name)
 
133
                raise NotDirectory("name %s is not a directory" % name)
131
134
            d.addCallback(is_directory)
132
135
            return d
133
136
 
138
141
        d.addCallback(lambda x: setattr(self, "cwd", full_path))
139
142
        return d
140
143
 
141
 
 
142
144
    @retry
143
145
    def mkfile(self, name):
144
146
        """make a file named name in cwd."""
145
147
        d = self.get_cwd_id()
146
148
        d.addCallback(lambda _:
147
 
            self.make_file(request.ROOT, self.cwd_id, name)
148
 
        )
 
149
            self.make_file(request.ROOT, self.cwd_id, name))
149
150
        return d
150
151
 
151
152
    def mkdir(self, name):
152
153
        """make a dir named name in cwd."""
153
154
        d = self.get_cwd_id()
154
155
        d.addCallback(lambda _:
155
 
            self.make_dir(request.ROOT, self.cwd_id, name)
156
 
        )
 
156
            self.make_dir(request.ROOT, self.cwd_id, name))
157
157
        return d
158
158
 
159
159
    def put(self, name, content):
176
176
        """get a dircontent list for cwd."""
177
177
        d = self.get_cwd()
178
178
        d.addCallback(self._get_content)
 
179
 
179
180
        def make_listdir(content):
180
181
            """parse dircontents."""
181
182
            result = []
193
194
            new_name = name
194
195
 
195
196
 
196
 
 
197
197
class EasyClientFactory(StorageClientFactory):
198
198
    """A test oriented protocol factory."""
199
 
    # no init: pylint: disable-msg=W0232
200
 
    # pylint: disable=W0232
201
 
 
202
199
    protocol = EasyClient
203
200
 
204
 
    def __init__(self, defer):
 
201
    def __init__(self, deferrer):
205
202
        """create a factory."""
206
 
        self.defer = defer
 
203
        self.client = None
 
204
        self.defer = deferrer
207
205
 
208
 
    def clientConnectionMade(self, client):
 
206
    def clientConnectionMade(self, client_obj):
209
207
        """on client connection made."""
210
 
        # pylint: disable-msg=W0201
211
 
        # pylint: disable=W0201
212
 
        self.client = client
213
 
        self.defer.callback(client)
 
208
        self.client = client_obj
 
209
        self.defer.callback(self.client)
214
210
 
215
211
    def clientConnectionFailed(self, connector, reason):
216
212
        """We failed at connecting."""
217
213
        self.defer.errback(reason)
218
214
 
 
215
 
219
216
def client(host, port):
220
217
    """return a deferred that will succeed with a connected client."""
221
218
    d = defer.Deferred()
223
220
    reactor.connectTCP(host, port, factory)
224
221
    return d
225
222
 
 
223
 
226
224
def authenticated_client(host, port, token="open sesame"):
227
225
    """return a deferred that will succeed with an authenticated client."""
228
226
    d = client(host, port)
229
 
    def auth(client):
 
227
 
 
228
    def auth(client_obj):
230
229
        """do the auth."""
231
230
        d = client.dummy_authenticate(token)
232
 
        d.addCallback(lambda _: client)
 
231
        d.addCallback(lambda _: client_obj)
233
232
        return d
234
233
    d.addCallback(auth)
235
234
    return d
236
235
 
 
236
 
237
237
def skip_error(failure, error):
238
238
    """try: except $error: pass errback"""
239
239
    if failure.check(request.StorageRequestError) and \
242
242
    else:
243
243
        return failure
244
244
 
 
245
 
245
246
# deferred utilities
246
247
skip_result = lambda _, f, *args, **kwargs: f(*args, **kwargs)
 
248
 
 
249
 
247
250
def sr_result(result, f, *args, **kwargs):
248
251
    """skip the result when calling the function and then return it."""
249
252
    f(*args, **kwargs)
250
253
    return result
251
254
 
 
255
 
252
256
def log(*args, **kwargs):
253
257
    """print args and kwargs."""
254
258
    for arg in args:
255
259
        print arg,
256
260
    print kwargs
257
261
 
 
262
 
258
263
def show_error(failure):
259
264
    """print the traceback."""
260
265
    print failure.getTraceback()
261
266
 
 
267
 
262
268
if __name__ == "__main__":
263
 
    vars = {'total': 0}
264
 
    # pylint: disable-msg=C0111
265
 
    # pylint: disable=C0111
266
269
 
267
 
    def create_dirs(client, num_dirs):
 
270
    def create_dirs(client_obj, num_dirs):
 
271
        """Create directories."""
268
272
        d = defer.succeed(None)
269
273
        for i in range(0, num_dirs):
270
 
            d.addCallback(skip_result, client.mkdir, "%s"%(i))
 
274
            d.addCallback(skip_result, client_obj.mkdir, "%s" % (i))
271
275
            d.addErrback(skip_error, protocol_pb2.Error.ALREADY_EXISTS)
272
 
            d.addCallback(skip_result, log, "Directory %s created."%i)
 
276
            d.addCallback(skip_result, log, "Directory %s created." % i)
273
277
        return d
274
278
 
275
 
    def make_files_client(client, number, num_files):
276
 
        d = client.chdir("%s"%(number))
 
279
    def make_files_client(client_obj, number, num_files):
 
280
        """Make files."""
 
281
        d = client_obj.chdir("%s" % (number))
277
282
        for i in range(0, num_files):
278
283
            d.addCallback(skip_result, log, "Client %s creating file %s."
279
284
                          % (number, i))
280
 
            d.addCallback(skip_result, client.mkfile, "%s"%(i))
 
285
            d.addCallback(skip_result, client.mkfile, "%s" % (i))
281
286
            d.addCallback(skip_result, log, "Client %s created file %s."
282
287
                          % (number, i))
283
288
        return d
285
290
    NUM_CLIENTS = 200
286
291
    NUM_FILES = 50
287
292
 
288
 
    port = int(open("tmp/ubuntuone-api.port").read())
289
 
    d = authenticated_client("localhost", int(port))
290
 
    d.addCallback(create_dirs, NUM_CLIENTS)
 
293
    port_num = int(open("tmp/ubuntuone-api.port").read())
 
294
    deferred = authenticated_client("localhost", int(port_num))
 
295
    deferred.addCallback(create_dirs, NUM_CLIENTS)
291
296
 
292
297
    def fire_clients(_):
 
298
        """Fire off the client connections."""
293
299
        dlist = []
294
300
        for i in range(NUM_CLIENTS):
295
 
            d = authenticated_client("localhost", int(port))
 
301
            d = authenticated_client("localhost", int(port_num))
296
302
            d.addCallback(sr_result, log, "client", i, "logged in")
297
303
            d.addCallback(make_files_client, i, NUM_FILES)
298
304
            d.addErrback(show_error)
300
306
 
301
307
        return defer.DeferredList(dlist)
302
308
 
303
 
    d.addCallback(fire_clients)
304
 
    d.addCallback(lambda _: reactor.stop())
305
 
    d.addErrback(show_error)
 
309
    deferred.addCallback(fire_clients)
 
310
    deferred.addCallback(lambda _: reactor.stop())
 
311
    deferred.addErrback(show_error)
306
312
    print "Starting reactor"
307
313
    start_time = time.time()
308
314
    reactor.run()