Merge lp:~terrycojones/txfluiddb/add-exists-tests-for-namespaces-and-tags into lp:txfluiddb

Proposed by Terry Jones
Status: Approved
Approved by: Tristan Seligmann
Approved revision: 16
Proposed branch: lp:~terrycojones/txfluiddb/add-exists-tests-for-namespaces-and-tags
Merge into: lp:txfluiddb
Diff against target: 245 lines (+171/-3)
3 files modified
setup.py (+1/-1)
txfluiddb/client.py (+61/-1)
txfluiddb/test/test_client.py (+109/-1)
To merge this branch: bzr merge lp:~terrycojones/txfluiddb/add-exists-tests-for-namespaces-and-tags
Reviewer Review Type Date Requested Status
Tristan Seligmann Approve
Review via email: mp+69934@code.launchpad.net

Description of the change

Adds 'exists' methods to Namespace and Tag to check if they exist.

To post a comment you must log in.
16. By Terry Jones

Bumped version number.

Revision history for this message
Tristan Seligmann (mithrandi) wrote :

Yay! Sorry it took so long to get around to reviewing this, but at least it's a positive review :)

review: Approve

Unmerged revisions

16. By Terry Jones

Bumped version number.

15. By Terry Jones

Added exists methods to Namespace and Tag classes.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'setup.py'
2--- setup.py 2010-09-15 12:14:01 +0000
3+++ setup.py 2011-07-31 21:39:23 +0000
4@@ -5,7 +5,7 @@
5
6 setup(
7 name = 'txfluiddb',
8- version = '0.1.0',
9+ version = '0.1.1',
10 packages = ['txfluiddb'],
11 author = 'Tristan Seligmann',
12 )
13
14=== modified file 'txfluiddb/client.py'
15--- txfluiddb/client.py 2010-06-13 21:53:12 +0000
16+++ txfluiddb/client.py 2011-07-31 21:39:23 +0000
17@@ -5,7 +5,7 @@
18 import simplejson as json
19
20 from txfluiddb.errors import InvalidName, InvalidTagValueType
21-from txfluiddb.http import getPage
22+from txfluiddb.http import getPage, HTTPError
23
24
25
26@@ -315,6 +315,36 @@
27 method='DELETE')
28
29
30+ def exists(self, endpoint):
31+ """
32+ Try a GET on the namespace to see if it exists.
33+
34+ @type endpoint: L{Endpoint}
35+ @param endpoint: The endpoint to operate through.
36+
37+ @rtype: C{Deferred} -> C{bool}
38+ @return: C{True} if the namespace exists, else C{False}.
39+ """
40+ def checkNonexistent(fail):
41+ """
42+ Return C{False} if the failure is due to a nonexistent namespace,
43+ else return the original failure.
44+
45+ @type fail: C{twisted.python.fail.Failure}
46+ @param fail: The failure.
47+ """
48+ fail.trap(HTTPError)
49+ errorClass = fail.value.response_headers.get(
50+ 'x-fluiddb-error-class')
51+ if errorClass and errorClass[0] == 'TNonexistentNamespace':
52+ return False
53+ return fail
54+
55+ url = self.getURL(endpoint)
56+ d = endpoint.submit(url=url, method='GET')
57+ return d.addCallbacks(lambda _: True, checkNonexistent)
58+
59+
60
61 class Tag(_HasPath, _HasPerms):
62 """
63@@ -368,6 +398,36 @@
64 method='DELETE')
65
66
67+ def exists(self, endpoint):
68+ """
69+ Try a GET on the tag to see if it exists.
70+
71+ @type endpoint: L{Endpoint}
72+ @param endpoint: The endpoint to operate through.
73+
74+ @rtype: C{Deferred} -> C{bool}
75+ @return: C{True} if the tag exists, else C{False}.
76+ """
77+ def checkNonexistent(fail):
78+ """
79+ Return C{False} if the failure is due to a nonexistent tag,
80+ else return the original failure.
81+
82+ @type fail: C{twisted.python.fail.Failure}
83+ @param fail: The failure.
84+ """
85+ fail.trap(HTTPError)
86+ errorClass = fail.value.response_headers.get(
87+ 'x-fluiddb-error-class')
88+ if errorClass and errorClass[0] == 'TNonexistentTag':
89+ return False
90+ return fail
91+
92+ url = self.getURL(endpoint)
93+ d = endpoint.submit(url=url, method='GET')
94+ return d.addCallbacks(lambda _: True, checkNonexistent)
95+
96+
97
98 class TagValues(_HasPath, _HasPerms):
99 """
100
101=== modified file 'txfluiddb/test/test_client.py'
102--- txfluiddb/test/test_client.py 2010-06-13 21:53:12 +0000
103+++ txfluiddb/test/test_client.py 2011-07-31 21:39:23 +0000
104@@ -1,11 +1,12 @@
105 from twisted.trial.unittest import TestCase
106-from twisted.internet.defer import succeed
107+from twisted.internet.defer import succeed, fail
108
109 import simplejson as json
110
111 from txfluiddb.errors import InvalidName
112 from txfluiddb.client import (
113 Namespace, Tag, Endpoint, _HasPath, Object, Blob, BasicCreds, loads)
114+from txfluiddb.http import HTTPError
115
116
117
118@@ -365,6 +366,49 @@
119 return d
120
121
122+ def test_existent(self):
123+ """
124+ Test retrieving a namespace that exists.
125+ """
126+ self.endpoint = MockEndpoint('http://fluiddb.url/')
127+ response = True
128+ self.endpoint.response = json.dumps(response)
129+
130+ def _gotResult(result):
131+ self.assertEqual(True, result)
132+
133+ d = self.namespace.exists(self.endpoint).addCallback(_gotResult)
134+ self.assertEqual(self.endpoint.method, 'GET')
135+ self.assertEqual(
136+ self.endpoint.url,
137+ 'http://fluiddb.url/namespaces/test')
138+ self.assertEqual(self.endpoint.data, None)
139+ return d
140+
141+
142+ def test_nonexistent(self):
143+ """
144+ Test retrieving a namespace that does not exist.
145+ """
146+ self.endpoint = MockFailingEndpoint('http://fluiddb.url/')
147+ response = False
148+ self.endpoint.response = json.dumps(response)
149+ self.endpoint.responseHeaders = {
150+ 'x-fluiddb-error-class' : ['TNonexistentNamespace']
151+ }
152+
153+ def _gotResult(result):
154+ self.assertEqual(False, result)
155+
156+ d = self.namespace.exists(self.endpoint).addErrback(_gotResult)
157+ self.assertEqual(self.endpoint.method, 'GET')
158+ self.assertEqual(
159+ self.endpoint.url,
160+ 'http://fluiddb.url/namespaces/test')
161+ self.assertEqual(self.endpoint.data, None)
162+ return d
163+
164+
165
166 class TagTests(TestCase):
167 """
168@@ -474,6 +518,49 @@
169 return d
170
171
172+ def test_existent(self):
173+ """
174+ Test retrieving a tag that exists.
175+ """
176+ self.endpoint = MockEndpoint('http://fluiddb.url/')
177+ response = True
178+ self.endpoint.response = json.dumps(response)
179+
180+ def _gotResult(result):
181+ self.assertEqual(True, result)
182+
183+ d = self.tag.exists(self.endpoint).addCallback(_gotResult)
184+ self.assertEqual(self.endpoint.method, 'GET')
185+ self.assertEqual(
186+ self.endpoint.url,
187+ 'http://fluiddb.url/tags/test/atag')
188+ self.assertEqual(self.endpoint.data, None)
189+ return d
190+
191+
192+ def test_nonexistent(self):
193+ """
194+ Test retrieving a tag that does not exist.
195+ """
196+ self.endpoint = MockFailingEndpoint('http://fluiddb.url/')
197+ response = False
198+ self.endpoint.response = json.dumps(response)
199+ self.endpoint.responseHeaders = {
200+ 'x-fluiddb-error-class' : ['TNonexistentTag']
201+ }
202+
203+ def _gotResult(result):
204+ self.assertEqual(False, result)
205+
206+ d = self.tag.exists(self.endpoint).addErrback(_gotResult)
207+ self.assertEqual(self.endpoint.method, 'GET')
208+ self.assertEqual(
209+ self.endpoint.url,
210+ 'http://fluiddb.url/tags/test/atag')
211+ self.assertEqual(self.endpoint.data, None)
212+ return d
213+
214+
215 class TagValuesTests(TestCase):
216 """
217 Tests for L{TagValues}. Note that these are tests on the permissions
218@@ -557,6 +644,27 @@
219
220
221
222+class MockFailingEndpoint(Endpoint):
223+ """
224+ Endpoint with (failing) submit mocked out.
225+ """
226+ def getPage(self, url, method, postdata=None, headers=None, *a, **kw):
227+ """
228+ Store our parameters instead of submitting a request.
229+ """
230+ if method == 'GET' and postdata is not None:
231+ raise RuntimeError('GET requests should never include postdata.')
232+ self.url = url
233+ self.method = method
234+ self.data = postdata
235+ self.headers = headers
236+ rc = self.responseCode if hasattr(self, 'responseCode') else 400
237+ message = self.message if hasattr(self, 'message') else ''
238+ rh = self.responseHeaders if hasattr(self, 'responseHeaders') else {}
239+ return fail(HTTPError(rc, message, self.response, rh))
240+
241+
242+
243 class EndpointTests(TestCase):
244 """
245 Tests for L{Endpoint}.

Subscribers

People subscribed via source and target branches

to all changes: