Merge lp:~jimbaker/pyjuju/rel-mgmt-endpoint-join into lp:pyjuju
- rel-mgmt-endpoint-join
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Gustavo Niemeyer |
Approved revision: | 119 |
Merged at revision: | 112 |
Proposed branch: | lp:~jimbaker/pyjuju/rel-mgmt-endpoint-join |
Merge into: | lp:pyjuju |
Diff against target: |
355 lines (+212/-51) 5 files modified
ensemble/formula/tests/repository/varnish/metadata.yaml (+7/-0) ensemble/formula/tests/repository/wordpress/metadata.yaml (+1/-1) ensemble/formula/tests/test_metadata.py (+3/-3) ensemble/state/service.py (+16/-4) ensemble/state/tests/test_service.py (+185/-43) |
To merge this branch: | bzr merge lp:~jimbaker/pyjuju/rel-mgmt-endpoint-join |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Gustavo Niemeyer | Approve | ||
Review via email: mp+42301@code.launchpad.net |
Commit message
Description of the change
Adds support for ServiceStateMan
It's good to see that contrary to my original feeling about the possible utility, this recipe actually implements useful functionality and is not just for demoing these ideas in executable pseudocode.
Kapil Thangavelu (hazmat) wrote : | # |
One question i had looking at this api is if it would pick up peer relations, or if those where intended to be handled separately.
Jim Baker (jimbaker) wrote : | # |
On Wed, Dec 1, 2010 at 5:48 PM, Kapil Thangavelu <
<email address hidden>> wrote:
> One question i had looking at this api is if it would pick up peer
> relations, or if those where intended to be handled separately.
>
>
Yes, it should handle peer relations, based on the fundamental method,
RelationEndpoin
this case, however, so I will fix that.
>
> --
>
> https:/
> You are the owner of lp:~jimbaker/ensemble/rel-mgmt-endpoint-join.
>
Gustavo Niemeyer (niemeyer) wrote : | # |
Jim, can you please provide some feedback on the above review as well? We generally try to
answer reviews on a point-by-point basis, both to personally track that something was done
about them, and also to provide some feedback to the reviewer and to the rest of the team
which is following the reviews.
Jim Baker (jimbaker) wrote : | # |
On Wed, Dec 1, 2010 at 8:56 AM, Gustavo Niemeyer <email address hidden>wrote:
> Review: Needs Information
> Thanks Jim. A couple of comments:
>
> [1]
>
> Given the specific context we're handling, what's the advantage of the
> approach used when compared to the straightforward option:
>
> result = []
> relation_set1 = yield self.get_
> relation_set2 = yield self.get_
> for relation1 in relation_set1:
> for relation2 in relation_set2:
> if relation1.
> result.
> return result
>
>
Both implement the nested loops join. The advantage of the recipe I wrote is
that it's designed for composability. Think about the idea of linq. At this
time, that's not in the picture, and usually isn't until we have more such
queries, or their variants (only care if at least one result exists, for
example).
So it probably makes more sense to just write it as you describe.
>
> [2]
>
> Individual tests which verify a specific intended aspect, including a nice
> docstring which explain its intended outcome, and perhaps some additional
> detail
> about why it might be wrong (in some situations), are generally more
> understandable and easier to maintain in the future.
>
Agreed, I've changed to adopt this practice in my latest branch on batch
topology changes.
Jim Baker (jimbaker) wrote : | # |
On Thu, Dec 2, 2010 at 4:41 AM, Gustavo Niemeyer <email address hidden>wrote:
> Review: Needs Information
> Jim, can you please provide some feedback on the above review as well? We
> generally try to
> answer reviews on a point-by-point basis, both to personally track that
> something was done
> about them, and also to provide some feedback to the reviewer and to the
> rest of the team
> which is following the reviews.
>
Sorry, I had gotten in the habit of making these responses when I had the
branch pushed in response to the feedback. But in this case certainly, and
probably others, it would be better to immediately respond.
- 110. By Jim Baker
-
Removed my relationalgebra library (sniff)
- 111. By Jim Baker
-
Removed no longer used RelationEndpoin
t.may_relate (used as a theta op) - 112. By Jim Baker
-
Removed no longer used RelationEndpoin
t.may_relate (used as a theta op) - 113. By Jim Baker
-
Split tests
- 114. By Jim Baker
-
Some docstring edits
Jim Baker (jimbaker) wrote : | # |
On Wed, Dec 1, 2010 at 8:47 PM, Jim Baker <email address hidden> wrote:
> On Wed, Dec 1, 2010 at 5:48 PM, Kapil Thangavelu <
> <email address hidden>> wrote:
>
> > One question i had looking at this api is if it would pick up peer
> > relations, or if those where intended to be handled separately.
> >
> >
> Yes, it should handle peer relations, based on the fundamental method,
> RelationEndpoin
> for
> this case, however, so I will fix that.
>
>
Added tests for peer relations.
>
>
Jim Baker (jimbaker) wrote : | # |
On Thu, Dec 2, 2010 at 9:42 AM, Jim Baker <email address hidden> wrote:
> On Wed, Dec 1, 2010 at 8:56 AM, Gustavo Niemeyer <email address hidden>wrote:
>
>> Review: Needs Information
>> Thanks Jim. A couple of comments:
>>
>> [1]
>>
>> Given the specific context we're handling, what's the advantage of the
>> approach used when compared to the straightforward option:
>>
>> result = []
>> relation_set1 = yield self.get_
>> relation_set2 = yield self.get_
>> for relation1 in relation_set1:
>> for relation2 in relation_set2:
>> if relation1.
>> result.
>> return result
>>
>>
> Both implement the nested loops join. The advantage of the recipe I wrote
> is that it's designed for composability. Think about the idea of linq. At
> this time, that's not in the picture, and usually isn't until we have more
> such queries, or their variants (only care if at least one result exists,
> for example).
>
> So it probably makes more sense to just write it as you describe.
>
In the latest version of the branch I pushed.
>
>
>>
>> [2]
>>
>> Individual tests which verify a specific intended aspect, including a nice
>> docstring which explain its intended outcome, and perhaps some additional
>> detail
>> about why it might be wrong (in some situations), are generally more
>> understandable and easier to maintain in the future.
>>
>
> Agreed, I've changed to adopt this practice in my latest branch on batch
> topology changes.
>
>
I have split these tests in the latest version of the branch.
Gustavo Niemeyer (niemeyer) wrote : | # |
Thanks for the refactoring Jim. A few additional points:
[3]
177 + """Test descriptor of the form ``<service name:relation name>``"""
178 + yield self.add_
179 + yield self.add_
The testing there looks a bit fragile, and not really covering the intended semantics
of matching the descriptor. Note that all of the results return exactly the same
thing, and that same thing is composed by the only possible relation which can match
for the given formulas.
[4]
Along the same lines, it doesn't look like any test returns more than a single pair,
with or without descriptors, so being able to see more than a single potential relation
isn't being covered.
[5]
10 +class BadRelation(
11 + """Descriptors describe an invalid relation.
That's unused and untested.
Jim Baker (jimbaker) wrote : | # |
Ready for review. Hopefully this is getting close!
On Tue, Dec 7, 2010 at 1:10 PM, Gustavo Niemeyer <email address hidden>wrote:
> Review: Needs Fixing
> Thanks for the refactoring Jim. A few additional points:
>
> [3]
>
> 177 + """Test descriptor of the form ``<service name:relation
> name>``"""
> 178 + yield self.add_
> 179 + yield self.add_
>
> The testing there looks a bit fragile, and not really covering the intended
> semantics
> of matching the descriptor. Note that all of the results return exactly
> the same
> thing, and that same thing is composed by the only possible relation which
> can match
> for the given formulas.
>
I reworked the testing to show more possible scenarios.
>
> [4]
>
> Along the same lines, it doesn't look like any test returns more than a
> single pair,
> with or without descriptors, so being able to see more than a single
> potential relation
> isn't being covered.
>
The revised tests demonstrate that If the relation name if not specified,
multiple endpoint pairs may be returned.
>
> [5]
>
> 10 +class BadRelation(
> 11 + """Descriptors describe an invalid relation.
>
> That's unused and untested.
>
This should have not been put in this branch, so I have removed it. It's
from an earlier design where we are not returning a set of endpoint pairs,
possibly empty, possibly more than one, but instead returned this exception.
Gustavo Niemeyer (niemeyer) wrote : | # |
Thanks for the fixes. Looks good, +1!
Preview Diff
1 | === added directory 'ensemble/formula/tests/repository/varnish' |
2 | === added file 'ensemble/formula/tests/repository/varnish/metadata.yaml' |
3 | --- ensemble/formula/tests/repository/varnish/metadata.yaml 1970-01-01 00:00:00 +0000 |
4 | +++ ensemble/formula/tests/repository/varnish/metadata.yaml 2010-12-10 05:02:12 +0000 |
5 | @@ -0,0 +1,7 @@ |
6 | +ensemble: formula |
7 | +name: varnish |
8 | +revision: 1 |
9 | +summary: "Database engine" |
10 | +description: "Another popular database" |
11 | +provides: |
12 | + webcache: varnish |
13 | |
14 | === modified file 'ensemble/formula/tests/repository/wordpress/metadata.yaml' |
15 | --- ensemble/formula/tests/repository/wordpress/metadata.yaml 2010-11-18 23:54:56 +0000 |
16 | +++ ensemble/formula/tests/repository/wordpress/metadata.yaml 2010-12-10 05:02:12 +0000 |
17 | @@ -14,7 +14,7 @@ |
18 | limit: 1 |
19 | optional: false |
20 | cache: |
21 | - interface: somecache |
22 | + interface: varnish |
23 | limit: 2 |
24 | optional: true |
25 | |
26 | |
27 | === modified file 'ensemble/formula/tests/test_metadata.py' |
28 | --- ensemble/formula/tests/test_metadata.py 2010-11-29 17:22:27 +0000 |
29 | +++ ensemble/formula/tests/test_metadata.py 2010-12-10 05:02:12 +0000 |
30 | @@ -202,7 +202,7 @@ |
31 | """Test the parsing of some well-known sample files""" |
32 | |
33 | def get_metadata(self, formula_name): |
34 | - """Get the associated metadata for a given formula, like ``wordpress``""" |
35 | + """Get the associated metadata for a given formula, eg ``wordpress``""" |
36 | metadata = MetaData(os.path.join( |
37 | test_repository_path, formula_name, "metadata.yaml")) |
38 | self.assertEqual(metadata.name, formula_name) |
39 | @@ -214,7 +214,7 @@ |
40 | Such relations are defined as follows:: |
41 | provides: |
42 | server: mysql |
43 | - """ |
44 | + """ |
45 | metadata = self.get_metadata("mysql") |
46 | self.assertEqual(metadata.peers, None) |
47 | self.assertEqual( |
48 | @@ -248,7 +248,7 @@ |
49 | {"interface": "mysql", "limit": 1, "optional": False}) |
50 | self.assertEqual( |
51 | metadata.requires["cache"], |
52 | - {"interface": "somecache", "limit": 2, "optional": True}) |
53 | + {"interface": "varnish", "limit": 2, "optional": True}) |
54 | |
55 | def test_reshape_interface_spec(self): |
56 | """Test rewriting of a given interface specification into long form. |
57 | |
58 | === modified file 'ensemble/state/service.py' |
59 | --- ensemble/state/service.py 2010-11-29 19:21:18 +0000 |
60 | +++ ensemble/state/service.py 2010-12-10 05:02:12 +0000 |
61 | @@ -66,15 +66,16 @@ |
62 | Returns the following: |
63 | |
64 | - Returns a set of matching endpoints, drawn from the peers, |
65 | - provides, and requires interfaces. The empty set if there |
66 | - are no endpoints matching the `descriptor`. |
67 | + provides, and requires interfaces. The empty set is |
68 | + returned if there are no endpoints matching the |
69 | + `descriptor`. |
70 | |
71 | - - Raises a BadDescriptor exception if the descriptor cannot |
72 | + - Raises a `BadDescriptor` exception if `descriptor` cannot |
73 | be parsed. |
74 | """ |
75 | tokens = descriptor.split(":") |
76 | if len(tokens) == 1 and bool(tokens[0]): |
77 | - query_service_name, query_relation_name = descriptor, None |
78 | + query_service_name, query_relation_name = descriptor, None |
79 | elif len(tokens) == 2 and bool(tokens[0]) and bool(tokens[1]): |
80 | query_service_name, query_relation_name = tokens |
81 | else: |
82 | @@ -100,6 +101,17 @@ |
83 | relation_role=relation_role)) |
84 | returnValue(endpoints) |
85 | |
86 | + @inlineCallbacks |
87 | + def join_descriptors(self, descriptor1, descriptor2): |
88 | + """Return a list of pairs of RelationEndpoints joining descriptors.""" |
89 | + result = [] |
90 | + relation_set1 = yield self.get_relation_endpoints(descriptor1) |
91 | + relation_set2 = yield self.get_relation_endpoints(descriptor2) |
92 | + for relation1 in relation_set1: |
93 | + for relation2 in relation_set2: |
94 | + if relation1.may_relate_to(relation2): |
95 | + result.append((relation1, relation2)) |
96 | + returnValue(result) |
97 | |
98 | class ServiceState(StateBase): |
99 | """State of a service registered in an environment. |
100 | |
101 | === modified file 'ensemble/state/tests/test_service.py' |
102 | --- ensemble/state/tests/test_service.py 2010-11-29 19:21:18 +0000 |
103 | +++ ensemble/state/tests/test_service.py 2010-12-10 05:02:12 +0000 |
104 | @@ -29,7 +29,7 @@ |
105 | self.machine_state_manager = MachineStateManager(self.client) |
106 | self.formula_state = yield self.formula_state_manager.add_formula_state( |
107 | "namespace", self.formula) |
108 | - self.relation_state_manager = None |
109 | + self.relation_state_manager = RelationStateManager(self.client) |
110 | |
111 | @inlineCallbacks |
112 | def add_service(self, name): |
113 | @@ -39,9 +39,6 @@ |
114 | |
115 | @inlineCallbacks |
116 | def add_relation(self, relation_type, *services): |
117 | - if not self.relation_state_manager: |
118 | - self.relation_state_manager = RelationStateManager(self.client) |
119 | - |
120 | relation_state = yield self.relation_state_manager.add_relation_state( |
121 | relation_type) |
122 | for service_meta in services: |
123 | @@ -641,48 +638,193 @@ |
124 | returnValue(service_state) |
125 | |
126 | @inlineCallbacks |
127 | - def test_get_relation_endpoints(self): |
128 | - """Test getting endpoints from their descriptors.""" |
129 | - |
130 | - # descriptor of the form ``<service name>`` |
131 | + def test_get_relation_endpoints_service_name(self): |
132 | + """Test getting endpoints with descriptor ``<service name>``""" |
133 | yield self.add_service_from_formula("wordpress") |
134 | - wp_endpoints = yield self.service_state_manager.get_relation_endpoints( |
135 | - "wordpress") |
136 | self.assertEqual( |
137 | - wp_endpoints, |
138 | + (yield self.service_state_manager.get_relation_endpoints( |
139 | + "wordpress")), |
140 | set([RelationEndpoint("wordpress", "http", "url", "provides"), |
141 | RelationEndpoint("wordpress", "mysql", "db", "requires"), |
142 | - RelationEndpoint("wordpress", "somecache", "cache", |
143 | - "requires")])) |
144 | - |
145 | - # descriptor of the form ``<service name:relation name>`` |
146 | - yield self.add_service_from_formula("riak") |
147 | - riak_endpoints = yield self.service_state_manager.get_relation_endpoints( |
148 | - "riak:ring") |
149 | - self.assertEqual( |
150 | - riak_endpoints, |
151 | + RelationEndpoint( |
152 | + "wordpress", "varnish", "cache", "requires")])) |
153 | + yield self.add_service_from_formula("riak") |
154 | + self.assertEqual( |
155 | + (yield self.service_state_manager.get_relation_endpoints( |
156 | + "riak")), |
157 | + set([RelationEndpoint("riak", "http", "admin", "provides"), |
158 | + RelationEndpoint("riak", "http", "endpoint", "provides"), |
159 | + RelationEndpoint("riak", "riak", "ring", "peers")])) |
160 | + |
161 | + @inlineCallbacks |
162 | + def test_get_relation_endpoints_service_name_relation_name(self): |
163 | + """Test getting endpoints with ``<service name:relation name>``""" |
164 | + yield self.add_service_from_formula("wordpress") |
165 | + self.assertEqual( |
166 | + (yield self.service_state_manager.get_relation_endpoints( |
167 | + "wordpress:url")), |
168 | + set([RelationEndpoint("wordpress", "http", "url", "provides")])) |
169 | + self.assertEqual( |
170 | + (yield self.service_state_manager.get_relation_endpoints( |
171 | + "wordpress:db")), |
172 | + set([RelationEndpoint("wordpress", "mysql", "db", "requires")])) |
173 | + self.assertEqual( |
174 | + (yield self.service_state_manager.get_relation_endpoints( |
175 | + "wordpress:cache")), |
176 | + set([RelationEndpoint( |
177 | + "wordpress", "varnish", "cache", "requires")])) |
178 | + yield self.add_service_from_formula("riak") |
179 | + self.assertEqual( |
180 | + (yield self.service_state_manager.get_relation_endpoints( |
181 | + "riak:ring")), |
182 | set([RelationEndpoint("riak", "riak", "ring", "peers")])) |
183 | |
184 | - # descriptor for a nonexistent formula |
185 | - yield self.add_service("nosuch") |
186 | - nosuch_endpoints = yield self.service_state_manager.get_relation_endpoints( |
187 | - "nosuch") |
188 | - self.assertEqual(nosuch_endpoints, set()) |
189 | - nosuch_endpoints2 = yield self.service_state_manager.get_relation_endpoints( |
190 | - "nosuch:nonsense") |
191 | - self.assertEqual(nosuch_endpoints2, set()) |
192 | - |
193 | - # bad descriptors |
194 | - try: |
195 | - _ = yield self.service_state_manager.get_relation_endpoints("a:b:c") |
196 | - except BadDescriptor: |
197 | - pass |
198 | - else: |
199 | - self.fail("Did not raise BadDescriptor") |
200 | - try: |
201 | - _ = yield self.service_state_manager.get_relation_endpoints("") |
202 | - except BadDescriptor: |
203 | - pass |
204 | - else: |
205 | - self.fail("Did not raise BadDescriptor") |
206 | - |
207 | + @inlineCallbacks |
208 | + def test_descriptor_for_services_without_formulas(self): |
209 | + """Test with services that have no corresponding formulas defined""" |
210 | + yield self.add_service("noformula") |
211 | + self.assertEqual( |
212 | + (yield self.service_state_manager.get_relation_endpoints( |
213 | + "noformula")), |
214 | + set()) |
215 | + self.assertEqual( |
216 | + (yield self.service_state_manager.get_relation_endpoints( |
217 | + "noformula:nonsense")), |
218 | + set()) |
219 | + |
220 | + @inlineCallbacks |
221 | + def test_descriptor_for_missing_service(self): |
222 | + """Test with a service that is not in the topology""" |
223 | + yield self.assertFailure( |
224 | + self.service_state_manager.get_relation_endpoints( |
225 | + "notadded"), |
226 | + ServiceStateNotFound) |
227 | + |
228 | + @inlineCallbacks |
229 | + def test_bad_descriptors(self): |
230 | + """Test that the descriptors meet the minimum naming standards""" |
231 | + yield self.assertFailure( |
232 | + self.service_state_manager.get_relation_endpoints("a:b:c"), |
233 | + BadDescriptor) |
234 | + yield self.assertFailure( |
235 | + self.service_state_manager.get_relation_endpoints(""), |
236 | + BadDescriptor) |
237 | + |
238 | + @inlineCallbacks |
239 | + def test_join_descriptors_service_name(self): |
240 | + """Test descriptor of the form ``<service name>`""" |
241 | + yield self.add_service_from_formula("wordpress") |
242 | + yield self.add_service_from_formula("mysql") |
243 | + self.assertEqual( |
244 | + (yield self.service_state_manager.join_descriptors( |
245 | + "wordpress", "mysql")), |
246 | + [(RelationEndpoint("wordpress", "mysql", "db", "requires"), |
247 | + RelationEndpoint("mysql", "mysql", "server", "provides"))]) |
248 | + # symmetric - note the pair has rotated |
249 | + self.assertEqual( |
250 | + (yield self.service_state_manager.join_descriptors( |
251 | + "mysql", "wordpress")), |
252 | + [(RelationEndpoint("mysql", "mysql", "server", "provides"), |
253 | + RelationEndpoint("wordpress", "mysql", "db", "requires"))]) |
254 | + yield self.add_service_from_formula("varnish") |
255 | + self.assertEqual( |
256 | + (yield self.service_state_manager.join_descriptors( |
257 | + "wordpress", "varnish")), |
258 | + [(RelationEndpoint("wordpress", "varnish", "cache", "requires"), |
259 | + RelationEndpoint("varnish", "varnish", "webcache", "provides"))]) |
260 | + |
261 | + @inlineCallbacks |
262 | + def test_join_descriptors_service_name_relation_name(self): |
263 | + """Test joining descriptors ``<service name:relation name>``""" |
264 | + yield self.add_service_from_formula("wordpress") |
265 | + yield self.add_service_from_formula("mysql") |
266 | + self.assertEqual( |
267 | + (yield self.service_state_manager.join_descriptors( |
268 | + "wordpress:db", "mysql")), |
269 | + [(RelationEndpoint("wordpress", "mysql", "db", "requires"), |
270 | + RelationEndpoint("mysql", "mysql", "server", "provides"))]) |
271 | + self.assertEqual( |
272 | + (yield self.service_state_manager.join_descriptors( |
273 | + "mysql:server", "wordpress")), |
274 | + [(RelationEndpoint("mysql", "mysql", "server", "provides"), |
275 | + RelationEndpoint("wordpress", "mysql", "db", "requires"))]) |
276 | + self.assertEqual( |
277 | + (yield self.service_state_manager.join_descriptors( |
278 | + "mysql:server", "wordpress:db")), |
279 | + [(RelationEndpoint("mysql", "mysql", "server", "provides"), |
280 | + RelationEndpoint("wordpress", "mysql", "db", "requires"))]) |
281 | + |
282 | + yield self.add_service_from_formula("varnish") |
283 | + self.assertEqual( |
284 | + (yield self.service_state_manager.join_descriptors( |
285 | + "wordpress:cache", "varnish")), |
286 | + [(RelationEndpoint("wordpress", "varnish", "cache", "requires"), |
287 | + RelationEndpoint("varnish", "varnish", "webcache", "provides"))]) |
288 | + self.assertEqual( |
289 | + (yield self.service_state_manager.join_descriptors( |
290 | + "wordpress:cache", "varnish:webcache")), |
291 | + [(RelationEndpoint("wordpress", "varnish", "cache", "requires"), |
292 | + RelationEndpoint("varnish", "varnish", "webcache", "provides"))]) |
293 | + |
294 | + @inlineCallbacks |
295 | + def test_join_peer_descriptors(self): |
296 | + """Test joining of peer relation descriptors""" |
297 | + yield self.add_service_from_formula("riak") |
298 | + self.assertEqual( |
299 | + (yield self.service_state_manager.join_descriptors( |
300 | + "riak", "riak")), |
301 | + [(RelationEndpoint("riak", "riak", "ring", "peers"), |
302 | + RelationEndpoint("riak", "riak", "ring", "peers"))]) |
303 | + self.assertEqual( |
304 | + (yield self.service_state_manager.join_descriptors( |
305 | + "riak:ring", "riak")), |
306 | + [(RelationEndpoint("riak", "riak", "ring", "peers"), |
307 | + RelationEndpoint("riak", "riak", "ring", "peers"))]) |
308 | + self.assertEqual( |
309 | + (yield self.service_state_manager.join_descriptors( |
310 | + "riak:ring", "riak:ring")), |
311 | + [(RelationEndpoint("riak", "riak", "ring", "peers"), |
312 | + RelationEndpoint("riak", "riak", "ring", "peers"))]) |
313 | + self.assertEqual( |
314 | + (yield self.service_state_manager.join_descriptors( |
315 | + "riak:no-ring", "riak:ring")), |
316 | + []) |
317 | + |
318 | + @inlineCallbacks |
319 | + def test_join_descriptors_no_common_relation(self): |
320 | + """Test joining of descriptors that do not share a relation""" |
321 | + yield self.add_service_from_formula("mysql") |
322 | + yield self.add_service_from_formula("riak") |
323 | + yield self.add_service_from_formula("wordpress") |
324 | + yield self.add_service_from_formula("varnish") |
325 | + self.assertEqual( |
326 | + (yield self.service_state_manager.join_descriptors( |
327 | + "mysql", "riak")), |
328 | + []) |
329 | + self.assertEqual( |
330 | + (yield self.service_state_manager.join_descriptors( |
331 | + "mysql:server", "riak:ring")), |
332 | + []) |
333 | + self.assertEqual( |
334 | + (yield self.service_state_manager.join_descriptors( |
335 | + "varnish", "mysql")), |
336 | + []) |
337 | + self.assertEqual( |
338 | + (yield self.service_state_manager.join_descriptors( |
339 | + "riak:ring", "riak:admin")), |
340 | + []) |
341 | + self.assertEqual( |
342 | + (yield self.service_state_manager.join_descriptors( |
343 | + "riak", "wordpress")), |
344 | + []) |
345 | + |
346 | + @inlineCallbacks |
347 | + def test_join_descriptors_no_service_state(self): |
348 | + """Test joining of nonexistent services""" |
349 | + yield self.add_service_from_formula("wordpress") |
350 | + yield self.assertFailure( |
351 | + self.service_state_manager.join_descriptors("wordpress", "nosuch"), |
352 | + ServiceStateNotFound) |
353 | + yield self.assertFailure( |
354 | + self.service_state_manager.join_descriptors("notyet", "nosuch"), |
355 | + ServiceStateNotFound) |
Thanks Jim. A couple of comments:
[1]
Given the specific context we're handling, what's the advantage of the
approach used when compared to the straightforward option:
result = [] relation_ endpoints( descriptor1) rleation_ endpoitns( descriptor2) may_relate_ to(relation2) :
result. append( (relation1, relation2))
relation_set1 = yield self.get_
relation_set2 = yield self.get_
for relation1 in relation_set1:
for relation2 in relation_set2:
if relation1.
return result
?
[2]
Individual tests which verify a specific intended aspect, including a nice
docstring which explain its intended outcome, and perhaps some additional detail
about why it might be wrong (in some situations), are generally more
understandable and easier to maintain in the future.
Please check out a few other test classes, such as the topology tests, to get an
idea about the way we've generally approached the problem.