1
+ #!/usr/bin/python
2
+ # -- Content-Encoding: UTF-8 --
1
3
"""
2
4
The tests in this file compare the request and response objects
3
5
to the JSON-RPC 2.0 specification document, as well as testing
4
- several internal components of the jsonrpclib library. Run this
6
+ several internal components of the jsonrpclib library. Run this
5
7
module without any parameters to run the tests.
6
8
7
- Currently, this is not easily tested with a framework like
9
+ Currently, this is not easily tested with a framework like
8
10
nosetests because we spin up a daemon thread running the
9
11
the Server, and nosetests (at least in my tests) does not
10
12
ever "kill" the thread.
11
13
12
14
If you are testing jsonrpclib and the module doesn't return to
13
- the command prompt after running the tests, you can hit
15
+ the command prompt after running the tests, you can hit
14
16
"Ctrl-C" (or "Ctrl-Break" on Windows) and that should kill it.
15
17
16
18
TODO:
17
19
* Finish implementing JSON-RPC 2.0 Spec tests
18
20
* Implement JSON-RPC 1.0 tests
19
21
* Implement JSONClass, History, Config tests
22
+
23
+ :license: Apache License 2.0
24
+ :version: 1.0.0
20
25
"""
21
26
27
+ # Module version
28
+ __version_info__ = (1 , 0 , 0 )
29
+ __version__ = "." .join (str (x ) for x in __version_info__ )
30
+
31
+ # Documentation strings format
32
+ __docformat__ = "restructuredtext en"
33
+
34
+ # ------------------------------------------------------------------------------
35
+
36
+ # jsonrpclib
22
37
from jsonrpclib import Server , MultiCall , ProtocolError
23
38
from jsonrpclib .SimpleJSONRPCServer import SimpleJSONRPCServer
24
- from jsonrpclib .SimpleJSONRPCServer import SimpleJSONRPCRequestHandler
25
39
from jsonrpclib .utils import from_bytes
26
-
27
- import socket
28
- import unittest
29
- import time
30
40
import jsonrpclib .history
31
41
42
+ # Standard library
32
43
import contextlib
33
44
import re
34
45
import sys
46
+ import threading
47
+ import time
48
+ import unittest
35
49
36
- if sys .version_info [0 ] < 3 :
50
+ try :
51
+ # Python 2
37
52
from StringIO import StringIO
38
53
39
- else :
54
+ except ImportError :
55
+ # Python 3
40
56
from io import StringIO
41
57
42
58
try :
43
59
import json
60
+
44
61
except ImportError :
45
62
import simplejson as json
46
- from threading import Thread
63
+
64
+ # ------------------------------------------------------------------------------
47
65
48
66
PORTS = list (range (8000 , 8999 ))
49
67
68
+ # ------------------------------------------------------------------------------
69
+ # Test methods
70
+
71
+ def subtract (minuend , subtrahend ):
72
+ """
73
+ Using the keywords from the JSON-RPC v2 doc
74
+ """
75
+ return minuend - subtrahend
76
+
77
+ def add (x , y ):
78
+ return x + y
79
+
80
+ def update (* args ):
81
+ return args
82
+
83
+ def summation (* args ):
84
+ return sum (args )
85
+
86
+ def notify_hello (* args ):
87
+ return args
88
+
89
+ def get_data ():
90
+ return ['hello' , 5 ]
91
+
92
+ def ping ():
93
+ return True
94
+
95
+ # ------------------------------------------------------------------------------
96
+ # Server utility class
97
+
98
+ class UtilityServer (object ):
99
+ """
100
+ Utility start/stop server
101
+ """
102
+ def __init__ (self ):
103
+ """
104
+ Sets up members
105
+ """
106
+ self ._server = None
107
+ self ._thread = None
108
+
109
+
110
+ def start (self , addr , port ):
111
+ """
112
+ Starts the server
113
+
114
+ :param addr: A binding address
115
+ :param port: A listening port
116
+ :return: This object (for in-line calls)
117
+ """
118
+ # Create the server
119
+ self ._server = server = SimpleJSONRPCServer ((addr , port ),
120
+ logRequests = False )
121
+
122
+ # Register test methods
123
+ server .register_function (summation , 'sum' )
124
+ server .register_function (summation , 'notify_sum' )
125
+ server .register_function (notify_hello )
126
+ server .register_function (subtract )
127
+ server .register_function (update )
128
+ server .register_function (get_data )
129
+ server .register_function (add )
130
+ server .register_function (ping )
131
+ server .register_function (summation , 'namespace.sum' )
132
+
133
+ # Serve in a thread
134
+ self ._thread = threading .Thread (target = server .serve_forever )
135
+ self ._thread .daemon = True
136
+ self ._thread .start ()
137
+
138
+ # Allow an in-line instantiation
139
+ return self
140
+
141
+
142
+ def stop (self ):
143
+ """
144
+ Stops the server and waits for its thread to finish
145
+ """
146
+ self ._server .shutdown ()
147
+ self ._server .server_close ()
148
+ self ._thread .join ()
149
+
150
+ self ._server = None
151
+ self ._thread = None
152
+
153
+ # ------------------------------------------------------------------------------
154
+
50
155
class TestCompatibility (unittest .TestCase ):
51
156
52
157
client = None
53
158
port = None
54
159
server = None
55
160
56
161
def setUp (self ):
162
+ """
163
+ Pre-test set up
164
+ """
165
+ # Set up the server
57
166
self .port = PORTS .pop ()
167
+ self .server = UtilityServer ().start ('' , self .port )
168
+
169
+ # Set up the client
58
170
self .history = jsonrpclib .history .History ()
59
- self .server = server_set_up (addr = ('' , self .port ))
60
171
self .client = Server ('http://localhost:{0}' .format (self .port ),
61
172
history = self .history )
62
173
174
+
175
+ def tearDown (self ):
176
+ """
177
+ Post-test clean up
178
+ """
179
+ # Close the client
180
+ self .client ("close" )
181
+
182
+ # Stop the server
183
+ self .server .stop ()
184
+
185
+
63
186
# v1 tests forthcoming
64
187
65
188
# Version 2.0 Tests
@@ -132,7 +255,7 @@ def test_non_existent_method(self):
132
255
def test_invalid_json (self ):
133
256
invalid_json = '{"jsonrpc": "2.0", "method": "foobar, ' + \
134
257
'"params": "bar", "baz]'
135
- response = self .client ._run_request (invalid_json )
258
+ self .client ._run_request (invalid_json )
136
259
response = json .loads (self .history .response )
137
260
verify_response = json .loads (
138
261
'{"jsonrpc": "2.0", "error": {"code": -32700,' +
@@ -143,7 +266,7 @@ def test_invalid_json(self):
143
266
144
267
def test_invalid_request (self ):
145
268
invalid_request = '{"jsonrpc": "2.0", "method": 1, "params": "bar"}'
146
- response = self .client ._run_request (invalid_request )
269
+ self .client ._run_request (invalid_request )
147
270
response = json .loads (self .history .response )
148
271
verify_response = json .loads (
149
272
'{"jsonrpc": "2.0", "error": {"code": -32600, ' +
@@ -155,7 +278,7 @@ def test_invalid_request(self):
155
278
def test_batch_invalid_json (self ):
156
279
invalid_request = '[ {"jsonrpc": "2.0", "method": "sum", ' + \
157
280
'"params": [1,2,4], "id": "1"},{"jsonrpc": "2.0", "method" ]'
158
- response = self .client ._run_request (invalid_request )
281
+ self .client ._run_request (invalid_request )
159
282
response = json .loads (self .history .response )
160
283
verify_response = json .loads (
161
284
'{"jsonrpc": "2.0", "error": {"code": -32700,' +
@@ -166,7 +289,7 @@ def test_batch_invalid_json(self):
166
289
167
290
def test_empty_array (self ):
168
291
invalid_request = '[]'
169
- response = self .client ._run_request (invalid_request )
292
+ self .client ._run_request (invalid_request )
170
293
response = json .loads (self .history .response )
171
294
verify_response = json .loads (
172
295
'{"jsonrpc": "2.0", "error": {"code": -32600, ' +
@@ -178,7 +301,7 @@ def test_empty_array(self):
178
301
def test_nonempty_array (self ):
179
302
invalid_request = '[1,2]'
180
303
request_obj = json .loads (invalid_request )
181
- response = self .client ._run_request (invalid_request )
304
+ self .client ._run_request (invalid_request )
182
305
response = json .loads (self .history .response )
183
306
self .assertTrue (len (response ) == len (request_obj ))
184
307
for resp in response :
@@ -208,7 +331,7 @@ def test_batch(self):
208
331
{"jsonrpc": "2.0", "method": "subtract", "params": [42,23], "id": "2"},
209
332
{"foo": "boo"},
210
333
{"jsonrpc": "2.0", "method": "foo.get", "params": {"name": "myself"}, "id": "5"},
211
- {"jsonrpc": "2.0", "method": "get_data", "id": "9"}
334
+ {"jsonrpc": "2.0", "method": "get_data", "id": "9"}
212
335
]""" )
213
336
214
337
# Thankfully, these are in order so testing is pretty simple.
@@ -267,19 +390,32 @@ def test_batch_notifications(self):
267
390
self .assertTrue (req == valid_req )
268
391
self .assertTrue (self .history .response == '' )
269
392
393
+ # ------------------------------------------------------------------------------
394
+
270
395
class InternalTests (unittest .TestCase ):
271
- """
272
- These tests verify that the client and server portions of
396
+ """
397
+ These tests verify that the client and server portions of
273
398
jsonrpclib talk to each other properly.
274
399
"""
275
- client = None
276
400
server = None
277
401
port = None
278
402
279
403
def setUp (self ):
404
+ # Set up the server
280
405
self .port = PORTS .pop ()
406
+ self .server = UtilityServer ().start ('' , self .port )
407
+
408
+ # Prepare the client
281
409
self .history = jsonrpclib .history .History ()
282
- self .server = server_set_up (addr = ('' , self .port ))
410
+
411
+
412
+ def tearDown (self ):
413
+ """
414
+ Post-test clean up
415
+ """
416
+ # Stop the server
417
+ self .server .stop ()
418
+
283
419
284
420
def get_client (self ):
285
421
return Server ('http://localhost:{0}' .format (self .port ),
@@ -315,7 +451,7 @@ def test_single_notify(self):
315
451
316
452
def test_single_namespace (self ):
317
453
client = self .get_client ()
318
- response = client .namespace .sum (1 , 2 , 4 )
454
+ client .namespace .sum (1 , 2 , 4 )
319
455
request = json .loads (self .history .request )
320
456
response = json .loads (self .history .response )
321
457
verify_request = {
@@ -361,12 +497,12 @@ def func():
361
497
return result [i ]
362
498
self .assertRaises (raises [i ], func )
363
499
500
+ # ------------------------------------------------------------------------------
364
501
365
502
class HeadersTests (unittest .TestCase ):
366
503
"""
367
504
These tests verify functionality of additional headers.
368
505
"""
369
- client = None
370
506
server = None
371
507
port = None
372
508
@@ -376,8 +512,17 @@ def setUp(self):
376
512
"""
377
513
Sets up the test
378
514
"""
515
+ # Set up the server
379
516
self .port = PORTS .pop ()
380
- self .server = server_set_up (addr = ('' , self .port ))
517
+ self .server = UtilityServer ().start ('' , self .port )
518
+
519
+
520
+ def tearDown (self ):
521
+ """
522
+ Post-test clean up
523
+ """
524
+ # Stop the server
525
+ self .server .stop ()
381
526
382
527
383
528
@contextlib .contextmanager
@@ -577,51 +722,7 @@ def test_should_allow_to_nest_additional_header_blocks(self):
577
722
self .assertTrue ('x-level-2' in headers2 )
578
723
self .assertEqual (headers2 ['x-level-2' ], '2' )
579
724
580
-
581
- """ Test Methods """
582
- def subtract (minuend , subtrahend ):
583
- """ Using the keywords from the JSON-RPC v2 doc """
584
- return minuend - subtrahend
585
-
586
- def add (x , y ):
587
- return x + y
588
-
589
- def update (* args ):
590
- return args
591
-
592
- def summation (* args ):
593
- return sum (args )
594
-
595
- def notify_hello (* args ):
596
- return args
597
-
598
- def get_data ():
599
- return ['hello' , 5 ]
600
-
601
- def ping ():
602
- return True
603
-
604
- def server_set_up (addr , address_family = socket .AF_INET ):
605
- # Not sure this is a good idea to spin up a new server thread
606
- # for each test... but it seems to work fine.
607
- def log_request (self , * args , ** kwargs ):
608
- """ Making the server output 'quiet' """
609
- pass
610
- SimpleJSONRPCRequestHandler .log_request = log_request
611
- server = SimpleJSONRPCServer (addr , address_family = address_family )
612
- server .register_function (summation , 'sum' )
613
- server .register_function (summation , 'notify_sum' )
614
- server .register_function (notify_hello )
615
- server .register_function (subtract )
616
- server .register_function (update )
617
- server .register_function (get_data )
618
- server .register_function (add )
619
- server .register_function (ping )
620
- server .register_function (summation , 'namespace.sum' )
621
- server_proc = Thread (target = server .serve_forever )
622
- server_proc .daemon = True
623
- server_proc .start ()
624
- return server_proc
725
+ # ------------------------------------------------------------------------------
625
726
626
727
if __name__ == '__main__' :
627
728
print ("===============================================================" )
0 commit comments