Skip to content

Commit 5e55049

Browse files
committed
Add tests for workspaces and agents endpoints
1 parent 990dfb5 commit 5e55049

File tree

1 file changed

+118
-1
lines changed

1 file changed

+118
-1
lines changed

src/test/groovy/CoderRestClientTest.groovy

Lines changed: 118 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,126 @@
11
package com.coder.gateway.sdk
22

3-
import spock.lang.*
3+
import com.coder.gateway.sdk.convertors.InstantConverter
4+
import com.coder.gateway.sdk.v2.models.Workspace
5+
import com.coder.gateway.sdk.v2.models.WorkspaceResource
6+
import com.coder.gateway.sdk.v2.models.WorkspacesResponse
7+
import com.google.gson.GsonBuilder
8+
import com.sun.net.httpserver.HttpExchange
9+
import com.sun.net.httpserver.HttpHandler
10+
import com.sun.net.httpserver.HttpServer
11+
import spock.lang.IgnoreIf
12+
import spock.lang.Requires
13+
import spock.lang.Specification
14+
import spock.lang.Unroll
15+
16+
import javax.net.ssl.HttpsURLConnection
17+
import java.time.Instant
418

519
@Unroll
620
class CoderRestClientTest extends Specification {
21+
/**
22+
* Create, start, and return a server that mocks the Coder API.
23+
*
24+
* The resources map to the workspace index (to avoid having to manually hardcode IDs everywhere since you cannot
25+
* use variables in the where blocks).
26+
*/
27+
def mockServer(List<Workspace> workspaces, List<List<WorkspaceResource>> resources = []) {
28+
HttpServer srv = HttpServer.create(new InetSocketAddress(0), 0)
29+
srv.createContext("/", new HttpHandler() {
30+
void handle(HttpExchange exchange) {
31+
int code = HttpURLConnection.HTTP_NOT_FOUND
32+
String response = "not found"
33+
try {
34+
def matcher = exchange.requestURI.path =~ /\/api\/v2\/templateversions\/([^\/]+)\/resources/
35+
if (matcher.size() == 1) {
36+
UUID templateVersionId = UUID.fromString(matcher[0][1])
37+
int idx = workspaces.findIndexOf { it.latestBuild.templateVersionID == templateVersionId }
38+
code = HttpURLConnection.HTTP_OK
39+
response = new GsonBuilder().registerTypeAdapter(Instant.class, new InstantConverter())
40+
.create().toJson(resources[idx])
41+
} else if (exchange.requestURI.path == "/api/v2/workspaces") {
42+
code = HttpsURLConnection.HTTP_OK
43+
response = new GsonBuilder().registerTypeAdapter(Instant.class, new InstantConverter())
44+
.create().toJson(new WorkspacesResponse(workspaces, workspaces.size()))
45+
}
46+
} catch (error) {
47+
// This will be a developer error.
48+
code = HttpURLConnection.HTTP_INTERNAL_ERROR
49+
response = error.message
50+
println(error.message) // Print since it will not show up in the error.
51+
}
52+
53+
byte[] body = response.getBytes()
54+
exchange.sendResponseHeaders(code, body.length)
55+
exchange.responseBody.write(body)
56+
exchange.close()
57+
}
58+
})
59+
srv.start()
60+
return [srv, "http://localhost:" + srv.address.port]
61+
}
62+
63+
def "gets workspaces"() {
64+
given:
65+
def (srv, url) = mockServer(workspaces)
66+
def client = new CoderRestClient(new URL(url), "token", null, "test")
67+
68+
expect:
69+
client.workspaces()*.name == expected
70+
71+
cleanup:
72+
srv.stop(0)
73+
74+
where:
75+
workspaces | expected
76+
[] | []
77+
[DataGen.workspace("ws1")] | ["ws1"]
78+
[DataGen.workspace("ws1"), DataGen.workspace("ws2")] | ["ws1", "ws2"]
79+
}
80+
81+
def "gets resources"() {
82+
given:
83+
def (srv, url) = mockServer(workspaces, resources)
84+
def client = new CoderRestClient(new URL(url), "token", null, "test")
85+
86+
expect:
87+
client.agents(workspaces).collect { it.agentID.toString() } == expected
88+
89+
cleanup:
90+
srv.stop(0)
91+
92+
where:
93+
workspaces << [
94+
[],
95+
[DataGen.workspace("ws1", [agent1: "3f51da1d-306f-4a40-ac12-62bda5bc5f9a"])],
96+
[DataGen.workspace("ws1", [agent1: "3f51da1d-306f-4a40-ac12-62bda5bc5f9a"])],
97+
[DataGen.workspace("ws1", [agent1: "3f51da1d-306f-4a40-ac12-62bda5bc5f9a"]),
98+
DataGen.workspace("ws2"),
99+
DataGen.workspace("ws3")],
100+
]
101+
resources << [
102+
[],
103+
[[]],
104+
[[DataGen.resource("agent2", "968eea5e-8787-439d-88cd-5bc440216a34"),
105+
DataGen.resource("agent3", "72fbc97b-952c-40c8-b1e5-7535f4407728")]],
106+
[[],
107+
[DataGen.resource("agent2", "968eea5e-8787-439d-88cd-5bc440216a34"),
108+
DataGen.resource("agent3", "72fbc97b-952c-40c8-b1e5-7535f4407728")],
109+
[]],
110+
]
111+
expected << [
112+
// Nothing, so no agents.
113+
[],
114+
// One workspace with an agent, but resources get overridden by the resources endpoint that returns
115+
// nothing so we end up with a workspace without an agent.
116+
["null"],
117+
// One workspace with an agent, but resources get overridden by the resources endpoint.
118+
["968eea5e-8787-439d-88cd-5bc440216a34", "72fbc97b-952c-40c8-b1e5-7535f4407728"],
119+
// Multiple workspaces but only one has resources from the resources endpoint.
120+
["null", "968eea5e-8787-439d-88cd-5bc440216a34", "72fbc97b-952c-40c8-b1e5-7535f4407728", "null"],
121+
]
122+
}
123+
7124
def "gets headers"() {
8125
expect:
9126
CoderRestClient.getHeaders(new URL("http://localhost"), command) == expected

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy