Merge lp:~wallyworld/gomaasapi/testservice-additions into lp:gomaasapi

Proposed by Ian Booth on 2015-01-13
Status: Merged
Merged at revision: 60
Proposed branch: lp:~wallyworld/gomaasapi/testservice-additions
Merge into: lp:gomaasapi
Diff against target: 180 lines (+127/-1)
2 files modified
testservice.go (+72/-1)
testservice_test.go (+55/-0)
To merge this branch: bzr merge lp:~wallyworld/gomaasapi/testservice-additions
Reviewer Review Type Date Requested Status
Andrew Wilkins 2015-01-13 Approve on 2015-01-13
Review via email: mp+246237@code.launchpad.net

Commit Message

Add capability to the test server to:

1. Filter instances using mem/arch/cpu-cores constraints when acquiring
2. Support new deployment_status api

Description of the Change

Add capability to the test server to:

1. Filter instances using mem/arch/cpu-cores constraints when acquiring
2. Support new deployment_status api

To post a comment you must log in.
Andrew Wilkins (axwalk) wrote :

LGTM. Suggest adding means of disabling ?op=deployment_status, but feel free to defer if you think it's not a high priority.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'testservice.go'
2--- testservice.go 2015-01-09 10:04:00 +0000
3+++ testservice.go 2015-01-13 00:22:44 +0000
4@@ -605,13 +605,41 @@
5 fmt.Fprint(w, string(res))
6 }
7
8+// nodeDeploymentStatusHandler handles requests for '/nodes/?op=deployment_status'.
9+func nodeDeploymentStatusHandler(server *TestServer, w http.ResponseWriter, r *http.Request) {
10+ values, err := url.ParseQuery(r.URL.RawQuery)
11+ checkError(err)
12+ nodes, _ := values["nodes"]
13+ var nodeStatus = make(map[string]interface{})
14+ for _, systemId := range nodes {
15+ node := server.nodes[systemId]
16+ field, err := node.GetField("status")
17+ if err != nil {
18+ continue
19+ }
20+ // The MAAS node model has changed somewhat since this test server was written.
21+ // For now, assume allocated = deployed, which is fine for testing with.
22+ switch field {
23+ case NodeStatusAllocated:
24+ nodeStatus[systemId] = "Deployed"
25+ default:
26+ nodeStatus[systemId] = "Not in Deployment"
27+ }
28+ }
29+ obj := maasify(server.client, nodeStatus)
30+ res, err := json.Marshal(obj)
31+ checkError(err)
32+ w.WriteHeader(http.StatusOK)
33+ fmt.Fprint(w, string(res))
34+}
35+
36 // findFreeNode looks for a node that is currently available, and
37 // matches the specified filter.
38 func findFreeNode(server *TestServer, filter url.Values) *MAASObject {
39 for systemID, node := range server.Nodes() {
40 _, present := server.OwnedNodes()[systemID]
41 if !present {
42- var agentName, nodeName, zoneName string
43+ var agentName, nodeName, zoneName, mem, cpuCores, arch string
44 for k := range filter {
45 switch k {
46 case "agent_name":
47@@ -620,6 +648,12 @@
48 nodeName = filter.Get(k)
49 case "zone":
50 zoneName = filter.Get(k)
51+ case "mem":
52+ mem = filter.Get(k)
53+ case "arch":
54+ arch = filter.Get(k)
55+ case "cpu-cores":
56+ cpuCores = filter.Get(k)
57 }
58 }
59 if nodeName != "" && !matchField(node, "hostname", nodeName) {
60@@ -628,6 +662,15 @@
61 if zoneName != "" && !matchField(node, "zone", zoneName) {
62 continue
63 }
64+ if mem != "" && !matchNumericField(node, "memory", mem) {
65+ continue
66+ }
67+ if arch != "" && !matchArchitecture(node, "architecture", arch) {
68+ continue
69+ }
70+ if cpuCores != "" && !matchNumericField(node, "cpu_count", cpuCores) {
71+ continue
72+ }
73 if agentName != "" {
74 agentNameObj := maasify(server.client, agentName)
75 node.GetMap()["agent_name"] = agentNameObj
76@@ -640,6 +683,31 @@
77 return nil
78 }
79
80+func matchArchitecture(node MAASObject, k, v string) bool {
81+ field, err := node.GetField(k)
82+ if err != nil {
83+ return false
84+ }
85+ baseArch := strings.Split(field, "/")
86+ return v == baseArch[0]
87+}
88+
89+func matchNumericField(node MAASObject, k, v string) bool {
90+ field, err := node.GetField(k)
91+ if err != nil {
92+ return false
93+ }
94+ nodeVal, err := strconv.ParseInt(field, 10, 64)
95+ if err != nil {
96+ return false
97+ }
98+ constraintVal, err := strconv.ParseInt(v, 10, 64)
99+ if err != nil {
100+ return false
101+ }
102+ return constraintVal <= nodeVal
103+}
104+
105 func matchField(node MAASObject, k, v string) bool {
106 field, err := node.GetField(k)
107 if err != nil {
108@@ -705,6 +773,9 @@
109 case r.Method == "GET" && op == "list":
110 // Node listing operation.
111 nodeListingHandler(server, w, r)
112+ case r.Method == "GET" && op == "deployment_status":
113+ // Node deployment_status operation.
114+ nodeDeploymentStatusHandler(server, w, r)
115 case r.Method == "POST" && op == "acquire":
116 nodesAcquireHandler(server, w, r)
117 case r.Method == "POST" && op == "release":
118
119=== modified file 'testservice_test.go'
120--- testservice_test.go 2015-01-09 10:04:00 +0000
121+++ testservice_test.go 2015-01-13 00:22:44 +0000
122@@ -1145,3 +1145,58 @@
123 c.Assert(id, Not(Equals), "n0")
124 c.Assert(zone, Equals, "z1")
125 }
126+
127+func (suite *TestMAASObjectSuite) TestAcquireFilterMemory(c *C) {
128+ suite.TestMAASObject.TestServer.NewNode(`{"system_id": "n0", "memory": "1024"}`)
129+ suite.TestMAASObject.TestServer.NewNode(`{"system_id": "n1", "memory": "2048"}`)
130+ nodeListing := suite.TestMAASObject.GetSubObject("nodes")
131+ jsonResponse, err := nodeListing.CallPost("acquire", url.Values{"mem": []string{"2048"}})
132+ c.Assert(err, IsNil)
133+ acquiredNode, err := jsonResponse.GetMAASObject()
134+ c.Assert(err, IsNil)
135+ mem, _ := acquiredNode.GetField("memory")
136+ c.Assert(mem, Equals, "2048")
137+}
138+
139+func (suite *TestMAASObjectSuite) TestAcquireFilterCpuCores(c *C) {
140+ suite.TestMAASObject.TestServer.NewNode(`{"system_id": "n0", "cpu_count": "1"}`)
141+ suite.TestMAASObject.TestServer.NewNode(`{"system_id": "n1", "cpu_count": "2"}`)
142+ nodeListing := suite.TestMAASObject.GetSubObject("nodes")
143+ jsonResponse, err := nodeListing.CallPost("acquire", url.Values{"cpu-cores": []string{"2"}})
144+ c.Assert(err, IsNil)
145+ acquiredNode, err := jsonResponse.GetMAASObject()
146+ c.Assert(err, IsNil)
147+ cores, _ := acquiredNode.GetField("cpu_count")
148+ c.Assert(cores, Equals, "2")
149+}
150+
151+func (suite *TestMAASObjectSuite) TestAcquireFilterArch(c *C) {
152+ suite.TestMAASObject.TestServer.NewNode(`{"system_id": "n0", "architecture": "amd64"}`)
153+ suite.TestMAASObject.TestServer.NewNode(`{"system_id": "n1", "architecture": "arm/generic"}`)
154+ nodeListing := suite.TestMAASObject.GetSubObject("nodes")
155+ jsonResponse, err := nodeListing.CallPost("acquire", url.Values{"arch": []string{"arm"}})
156+ c.Assert(err, IsNil)
157+ acquiredNode, err := jsonResponse.GetMAASObject()
158+ c.Assert(err, IsNil)
159+ arch, _ := acquiredNode.GetField("architecture")
160+ c.Assert(arch, Equals, "arm/generic")
161+}
162+
163+func (suite *TestMAASObjectSuite) TestDeploymentStatus(c *C) {
164+ suite.TestMAASObject.TestServer.NewNode(`{"system_id": "n0", "status": "6"}`)
165+ suite.TestMAASObject.TestServer.NewNode(`{"system_id": "n1", "status": "1"}`)
166+ nodes := suite.TestMAASObject.GetSubObject("nodes")
167+ jsonResponse, err := nodes.CallGet("deployment_status", url.Values{"nodes": []string{"n0", "n1"}})
168+ c.Assert(err, IsNil)
169+ deploymentStatus, err := jsonResponse.GetMap()
170+ c.Assert(err, IsNil)
171+ c.Assert(deploymentStatus, HasLen, 2)
172+ expectedStatus := map[string]string{
173+ "n0": "Deployed", "n1": "Not in Deployment",
174+ }
175+ for systemId, status := range expectedStatus {
176+ nodeStatus, err := deploymentStatus[systemId].GetString()
177+ c.Assert(err, IsNil)
178+ c.Assert(nodeStatus, Equals, status)
179+ }
180+}

Subscribers

People subscribed via source and target branches

to all changes: