Merge lp:~themue/pyjuju/go into lp:pyjuju/go

Proposed by Frank Mueller
Status: Rejected
Rejected by: Gustavo Niemeyer
Proposed branch: lp:~themue/pyjuju/go
Merge into: lp:pyjuju/go
Diff against target: 125 lines (+57/-9)
3 files modified
state/relation.go (+21/-1)
state/state.go (+11/-7)
state/state_test.go (+25/-1)
To merge this branch: bzr merge lp:~themue/pyjuju/go
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+103315@code.launchpad.net

Description of the change

Added ResolvedWatcher for Units.

It reads the resolved mode out of the node content if
it's created or changed.

https://codereview.appspot.com/6120045/

To post a comment you must log in.
Revision history for this message
Gustavo Niemeyer (niemeyer) wrote :

Very nice. Just doc suggestions, except for the missing ok check,
similar to what was done in the other branches.

https://codereview.appspot.com/6120045/diff/1/state/unit.go
File state/unit.go (right):

https://codereview.appspot.com/6120045/diff/1/state/unit.go#newcode470
state/unit.go:470: // and checks if it's valid.
// parseResolvedMode returns the resolved mode serialized
// in yaml if it is valid, or an error otherwise.

https://codereview.appspot.com/6120045/diff/1/state/unit.go#newcode486
state/unit.go:486: // resolved mode are used.
// validResolvedMode returns an error if the provided
// mode isn't valid. ResolvedNone is only considered a
// valid mode if acceptNone is true.

https://codereview.appspot.com/6120045/diff/1/state/unit.go#newcode563
state/unit.go:563: // ResolvedWatcher observes changes to a resolved
flag node.
// ResolvedWatcher observes changes to a unit's resolved
// mode. See SetResolved for details.

https://codereview.appspot.com/6120045/diff/1/state/unit.go#newcode573
state/unit.go:573: // watcher for the given path.
// newResolvedWatcher returns a new ResolvedWatcher watching path.

https://codereview.appspot.com/6120045/diff/1/state/unit.go#newcode613
state/unit.go:613: case change := <-w.watcher.Changes():
This needs to check for ok in a similar way to what was done in the
other watchers.

https://codereview.appspot.com/6120045/

Revision history for this message
Gustavo Niemeyer (niemeyer) wrote :
Revision history for this message
Gustavo Niemeyer (niemeyer) wrote :

<niemeyer> TheMue: You've just reproposed a branch that has already been
submitted: https://codereview.appspot.com/6120045/
<niemeyer> TheMue: Probably because of the vague branch name ("go")

https://codereview.appspot.com/6120045/

Unmerged revisions

202. By Frank Mueller

state: Merged prerequisite.

201. By Frank Mueller

state: Preparing for prerequisite.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'state/relation.go'
2--- state/relation.go 2012-05-31 16:19:15 +0000
3+++ state/relation.go 2012-06-06 13:01:07 +0000
4@@ -1,6 +1,8 @@
5 package state
6
7-import ()
8+import (
9+ "fmt"
10+)
11
12 // RelationRole defines the role of a relation endpoint.
13 type RelationRole string
14@@ -47,6 +49,24 @@
15 return e.ServiceName + ":" + e.RelationName
16 }
17
18+// checkValues performs basic tests on the endpoint data without
19+// checking the validity of identifiers.
20+func (e *RelationEndpoint) checkValues() error {
21+ switch {
22+ case e.ServiceName == "":
23+ return fmt.Errorf("endpoint has empty service name")
24+ case e.Interface == "":
25+ return fmt.Errorf("endpoint has empty interface")
26+ case e.RelationName == "":
27+ return fmt.Errorf("endpoint has empty relation name")
28+ case e.RelationRole != RoleProvider && e.RelationRole != RoleRequirer && e.RelationRole != RolePeer:
29+ return fmt.Errorf("endpoint has invalid role: %q", e.RelationRole)
30+ case e.RelationScope != ScopeGlobal && e.RelationScope != ScopeContainer:
31+ return fmt.Errorf("endpoint has invalid scope: %q", e.RelationScope)
32+ }
33+ return nil
34+}
35+
36 // Relation represents a link between services, or within a
37 // service (in the case of peer relations).
38 type Relation struct {
39
40=== modified file 'state/state.go'
41--- state/state.go 2012-06-05 21:31:50 +0000
42+++ state/state.go 2012-06-06 13:01:07 +0000
43@@ -312,11 +312,19 @@
44 return nil, nil, fmt.Errorf("relation already exists")
45 }
46 scope := ScopeGlobal
47+ serviceKeys := make(map[RelationEndpoint]string)
48 for _, endpoint := range endpoints {
49 if endpoint.RelationScope == ScopeContainer {
50 scope = ScopeContainer
51- break
52- }
53+ }
54+ if err := endpoint.checkValues(); err != nil {
55+ return nil, nil, err
56+ }
57+ serviceKey, err := t.ServiceKey(endpoint.ServiceName)
58+ if err != nil {
59+ return nil, nil, err
60+ }
61+ serviceKeys[endpoint] = serviceKey
62 }
63 // Add a new relation node depending on the scope. Afterwards
64 // create a node and a service relation per endpoint.
65@@ -326,10 +334,6 @@
66 }
67 serviceRelations := []*ServiceRelation{}
68 for _, endpoint := range endpoints {
69- serviceKey, err := t.ServiceKey(endpoint.ServiceName)
70- if err != nil {
71- return nil, nil, err
72- }
73 // The relation endpoint node is only created if the scope is
74 // global. In case of container scoped relations the creation
75 // per container occurs in ServiceRelation.AddUnit.
76@@ -341,7 +345,7 @@
77 serviceRelations = append(serviceRelations, &ServiceRelation{
78 st: s,
79 relationKey: relationKey,
80- serviceKey: serviceKey,
81+ serviceKey: serviceKeys[endpoint],
82 relationScope: endpoint.RelationScope,
83 relationRole: endpoint.RelationRole,
84 relationName: endpoint.RelationName,
85
86=== modified file 'state/state_test.go'
87--- state/state_test.go 2012-06-06 10:17:40 +0000
88+++ state/state_test.go 2012-06-06 13:01:07 +0000
89@@ -1085,7 +1085,6 @@
90 c.Assert(serviceRelations[0].RelationScope(), Equals, state.ScopeGlobal)
91 c.Assert(serviceRelations[0].RelationRole(), Equals, state.RolePeer)
92 c.Assert(serviceRelations[0].RelationName(), Equals, "cache")
93-
94 }
95
96 func (s *StateSuite) TestAddRelationMissingService(c *C) {
97@@ -1169,3 +1168,28 @@
98 c.Assert(err, IsNil)
99 c.Assert(env.Map(), DeepEquals, map[string]interface{}{"type": "dummy", "name": "foo"})
100 }
101+
102+func (s *StateSuite) TestAddRelationInvalidEndpoints(c *C) {
103+ dummy := s.addDummyCharm(c)
104+ s.st.AddService("riak", dummy)
105+ // Empty service name.
106+ riakep := state.RelationEndpoint{"", "ring", "cache", state.RolePeer, state.ScopeGlobal}
107+ _, _, err := s.st.AddRelation(riakep)
108+ c.Assert(err, ErrorMatches, `endpoint has empty service name`)
109+ // Empty interface.
110+ riakep = state.RelationEndpoint{"riak", "", "cache", state.RolePeer, state.ScopeGlobal}
111+ _, _, err = s.st.AddRelation(riakep)
112+ c.Assert(err, ErrorMatches, `endpoint has empty interface`)
113+ // Empty relation name.
114+ riakep = state.RelationEndpoint{"riak", "ring", "", state.RolePeer, state.ScopeGlobal}
115+ _, _, err = s.st.AddRelation(riakep)
116+ c.Assert(err, ErrorMatches, `endpoint has empty relation name`)
117+ // Invalid role.
118+ riakep = state.RelationEndpoint{"riak", "ring", "cache", state.RelationRole("foo"), state.ScopeGlobal}
119+ _, _, err = s.st.AddRelation(riakep)
120+ c.Assert(err, ErrorMatches, `can't add non-peer relation with a single service`)
121+ // Invalid role.
122+ riakep = state.RelationEndpoint{"riak", "ring", "cache", state.RolePeer, state.RelationScope("foo")}
123+ _, _, err = s.st.AddRelation(riakep)
124+ c.Assert(err, ErrorMatches, `endpoint has invalid scope: "foo"`)
125+}

Subscribers

People subscribed via source and target branches