Skip to content

Commit f1dcd00

Browse files
committed
add unit tests
1 parent c6abed1 commit f1dcd00

File tree

8 files changed

+1878
-203
lines changed

8 files changed

+1878
-203
lines changed

plugins/dns/powerdns/src/test/java/org/apache/cloudstack/dns/powerdns/PowerDnsClientTest.java

Lines changed: 276 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,65 @@
1818
package org.apache.cloudstack.dns.powerdns;
1919

2020
import static org.junit.Assert.assertEquals;
21+
import static org.junit.Assert.assertNotNull;
22+
import static org.junit.Assert.assertTrue;
23+
import static org.mockito.ArgumentMatchers.any;
24+
import static org.mockito.Mockito.mock;
25+
import static org.mockito.Mockito.when;
2126

27+
import java.io.IOException;
28+
import java.nio.charset.StandardCharsets;
29+
import java.util.Arrays;
30+
31+
import org.apache.cloudstack.dns.exception.DnsOperationException;
32+
import org.apache.cloudstack.dns.exception.DnsAuthenticationException;
33+
import org.apache.cloudstack.dns.exception.DnsConflictException;
34+
import org.apache.cloudstack.dns.exception.DnsNotFoundException;
35+
import org.apache.http.StatusLine;
36+
import org.apache.http.client.methods.CloseableHttpResponse;
37+
import org.apache.http.client.methods.HttpUriRequest;
38+
import org.apache.http.entity.StringEntity;
39+
import org.apache.http.impl.client.CloseableHttpClient;
40+
import org.junit.Before;
2241
import org.junit.Test;
23-
import org.mockito.InjectMocks;
42+
import org.junit.runner.RunWith;
43+
import org.mockito.invocation.InvocationOnMock;
44+
import org.mockito.junit.MockitoJUnitRunner;
45+
import org.mockito.stubbing.Answer;
46+
import org.springframework.test.util.ReflectionTestUtils;
47+
48+
import com.fasterxml.jackson.databind.JsonNode;
2449

50+
@RunWith(MockitoJUnitRunner.class)
2551
public class PowerDnsClientTest {
26-
@InjectMocks
27-
PowerDnsClient client = new PowerDnsClient();
52+
53+
PowerDnsClient client;
54+
CloseableHttpClient httpClientMock;
55+
56+
@Before
57+
public void setUp() {
58+
client = new PowerDnsClient();
59+
httpClientMock = mock(CloseableHttpClient.class);
60+
ReflectionTestUtils.setField(client, "httpClient", httpClientMock);
61+
}
62+
63+
private CloseableHttpResponse createResponse(int statusCode, String jsonBody) {
64+
CloseableHttpResponse responseMock = mock(CloseableHttpResponse.class);
65+
StatusLine statusLineMock = mock(StatusLine.class);
66+
when(responseMock.getStatusLine()).thenReturn(statusLineMock);
67+
when(statusLineMock.getStatusCode()).thenReturn(statusCode);
68+
69+
if (jsonBody != null) {
70+
when(responseMock.getEntity()).thenReturn(new StringEntity(jsonBody, StandardCharsets.UTF_8));
71+
}
72+
73+
return responseMock;
74+
}
75+
76+
private void mockHttpResponse(int statusCode, String jsonBody) throws IOException {
77+
CloseableHttpResponse response = createResponse(statusCode, jsonBody);
78+
when(httpClientMock.execute(any(HttpUriRequest.class))).thenReturn(response);
79+
}
2880

2981
@Test
3082
public void testNormalizeApexRecord() {
@@ -80,4 +132,225 @@ public void testNormalizeZoneNormalization() {
80132
result = client.normalizeRecordName("www", "example.com.");
81133
assertEquals("www.example.com.", result);
82134
}
135+
136+
@Test
137+
public void testDiscoverAuthoritativeServerIdSuccess() throws Exception {
138+
mockHttpResponse(200, "[{\"id\":\"localhost\", \"daemon_type\":\"authoritative\"}]");
139+
String result = client.discoverAuthoritativeServerId("http://pdns:8081", null, "apikey");
140+
assertEquals("localhost", result);
141+
}
142+
143+
@Test
144+
public void testDiscoverAuthoritativeServerIdFallback() throws Exception {
145+
mockHttpResponse(200, "[{\"id\":\"server1\", \"daemon_type\":\"recursor\"}, {\"id\":\"server2\", \"daemon_type\":\"authoritative\"}]");
146+
String result = client.discoverAuthoritativeServerId("http://pdns", 8081, "apikey");
147+
assertEquals("server2", result);
148+
}
149+
150+
@Test(expected = DnsOperationException.class)
151+
public void testDiscoverAuthoritativeServerIdEmpty() throws Exception {
152+
mockHttpResponse(200, "[]");
153+
client.discoverAuthoritativeServerId("http://pdns", 8081, "apikey");
154+
}
155+
156+
@Test(expected = DnsOperationException.class)
157+
public void testDiscoverAuthoritativeServerIdNoAuthoritative() throws Exception {
158+
mockHttpResponse(200, "[{\"id\":\"server1\", \"daemon_type\":\"recursor\"}]");
159+
client.discoverAuthoritativeServerId("http://pdns", 8081, "apikey");
160+
}
161+
162+
@Test
163+
public void testValidateServerIdSuccess() throws Exception {
164+
mockHttpResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"authoritative\"}");
165+
String result = client.validateServerId("http://pdns", 8081, "apikey", "abc");
166+
assertEquals("abc", result);
167+
}
168+
169+
@Test(expected = DnsOperationException.class)
170+
public void testValidateServerIdNotAuthoritative() throws Exception {
171+
mockHttpResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"recursor\"}");
172+
client.validateServerId("http://pdns", 8081, "apikey", "abc");
173+
}
174+
175+
@Test
176+
public void testResolveServerIdWithExternalId() throws Exception {
177+
mockHttpResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"authoritative\"}");
178+
String result = client.resolveServerId("http://pdns", 8081, "apikey", "abc");
179+
assertEquals("abc", result);
180+
}
181+
182+
@Test
183+
public void testResolveServerIdWithoutExternalId() throws Exception {
184+
mockHttpResponse(200, "[{\"id\":\"localhost\", \"daemon_type\":\"authoritative\"}]");
185+
String result = client.resolveServerId("http://pdns", 8081, "apikey", null);
186+
assertEquals("localhost", result);
187+
}
188+
189+
@Test
190+
public void testCreateZone() throws Exception {
191+
when(httpClientMock.execute(any(HttpUriRequest.class))).thenAnswer(new Answer<CloseableHttpResponse>() {
192+
@Override
193+
public CloseableHttpResponse answer(InvocationOnMock invocation) {
194+
HttpUriRequest request = invocation.getArgument(0);
195+
if (request.getMethod().equals("GET")) {
196+
return createResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"authoritative\"}");
197+
}
198+
if (request.getMethod().equals("POST")) {
199+
return createResponse(201, "{\"id\":\"example.com.\"}");
200+
}
201+
return createResponse(500, null);
202+
}
203+
});
204+
205+
String result = client.createZone("http://pdns", 8081, "apikey", "abc", "example.com", "Native", false, Arrays.asList("ns1.com"));
206+
assertEquals("example.com.", result);
207+
}
208+
209+
@Test
210+
public void testUpdateZone() throws Exception {
211+
when(httpClientMock.execute(any(HttpUriRequest.class))).thenAnswer(new Answer<CloseableHttpResponse>() {
212+
@Override
213+
public CloseableHttpResponse answer(InvocationOnMock invocation) {
214+
HttpUriRequest request = invocation.getArgument(0);
215+
if (request.getMethod().equals("GET")) {
216+
return createResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"authoritative\"}");
217+
}
218+
if (request.getMethod().equals("PUT")) {
219+
return createResponse(204, null);
220+
}
221+
return createResponse(500, null);
222+
}
223+
});
224+
225+
client.updateZone("http://pdns", 8081, "apikey", "abc", "example.com", "Native", true, Arrays.asList("ns1.com"));
226+
// No exception means success
227+
}
228+
229+
@Test
230+
public void testDeleteZone() throws Exception {
231+
when(httpClientMock.execute(any(HttpUriRequest.class))).thenAnswer(new Answer<CloseableHttpResponse>() {
232+
@Override
233+
public CloseableHttpResponse answer(InvocationOnMock invocation) {
234+
HttpUriRequest request = invocation.getArgument(0);
235+
if (request.getMethod().equals("GET")) {
236+
return createResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"authoritative\"}");
237+
}
238+
if (request.getMethod().equals("DELETE")) {
239+
return createResponse(204, null);
240+
}
241+
return createResponse(500, null);
242+
}
243+
});
244+
245+
client.deleteZone("http://pdns", 8081, "apikey", "abc", "example.com");
246+
}
247+
248+
@Test
249+
public void testModifyRecord() throws Exception {
250+
when(httpClientMock.execute(any(HttpUriRequest.class))).thenAnswer(new Answer<CloseableHttpResponse>() {
251+
@Override
252+
public CloseableHttpResponse answer(InvocationOnMock invocation) {
253+
HttpUriRequest request = invocation.getArgument(0);
254+
if (request.getMethod().equals("GET")) {
255+
return createResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"authoritative\"}");
256+
}
257+
if (request.getMethod().equals("PATCH")) {
258+
return createResponse(204, null);
259+
}
260+
return createResponse(500, null);
261+
}
262+
});
263+
264+
String result = client.modifyRecord("http://pdns", 8081, "apikey", "abc", "example.com", "www", "A", 300, Arrays.asList("1.2.3.4"), "REPLACE");
265+
assertEquals("www.example.com", result);
266+
}
267+
268+
@Test
269+
public void testModifyRecordApex() throws Exception {
270+
when(httpClientMock.execute(any(HttpUriRequest.class))).thenAnswer(new Answer<CloseableHttpResponse>() {
271+
@Override
272+
public CloseableHttpResponse answer(InvocationOnMock invocation) {
273+
HttpUriRequest request = invocation.getArgument(0);
274+
if (request.getMethod().equals("GET")) {
275+
return createResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"authoritative\"}");
276+
}
277+
if (request.getMethod().equals("PATCH")) {
278+
return createResponse(204, null);
279+
}
280+
return createResponse(500, null);
281+
}
282+
});
283+
284+
String result = client.modifyRecord("http://pdns", 8081, "apikey", "abc", "example.com", "@", "A", 300, Arrays.asList("1.2.3.4"), "REPLACE");
285+
assertEquals("example.com", result);
286+
}
287+
288+
@Test
289+
public void testListRecords() throws Exception {
290+
when(httpClientMock.execute(any(HttpUriRequest.class))).thenAnswer(new Answer<CloseableHttpResponse>() {
291+
@Override
292+
public CloseableHttpResponse answer(InvocationOnMock invocation) {
293+
HttpUriRequest request = invocation.getArgument(0);
294+
// validateServerId uses /servers/abc
295+
// listRecords uses /servers/abc/zones/example.com.
296+
if (request.getURI().getPath().endsWith("abc")) {
297+
return createResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"authoritative\"}");
298+
}
299+
if (request.getURI().getPath().endsWith("example.com.")) {
300+
return createResponse(200, "{\"rrsets\":[{\"name\":\"www.example.com.\",\"type\":\"A\"}]}");
301+
}
302+
return createResponse(500, null);
303+
}
304+
});
305+
306+
Iterable<JsonNode> records = client.listRecords("http://pdns", 8081, "apikey", "abc", "example.com");
307+
assertNotNull(records);
308+
assertTrue(records.iterator().hasNext());
309+
assertEquals("www.example.com.", records.iterator().next().path("name").asText());
310+
}
311+
312+
@Test
313+
public void testListRecordsEmpty() throws Exception {
314+
when(httpClientMock.execute(any(HttpUriRequest.class))).thenAnswer(new Answer<CloseableHttpResponse>() {
315+
@Override
316+
public CloseableHttpResponse answer(InvocationOnMock invocation) {
317+
HttpUriRequest request = invocation.getArgument(0);
318+
if (request.getURI().getPath().endsWith("abc")) {
319+
return createResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"authoritative\"}");
320+
}
321+
if (request.getURI().getPath().endsWith("example.com.")) {
322+
return createResponse(200, "{}");
323+
}
324+
return createResponse(500, null);
325+
}
326+
});
327+
328+
Iterable<JsonNode> records = client.listRecords("http://pdns", 8081, "apikey", "abc", "example.com");
329+
assertNotNull(records);
330+
assertTrue(!records.iterator().hasNext());
331+
}
332+
333+
@Test(expected = DnsNotFoundException.class)
334+
public void testExecuteThrowsNotFound() throws Exception {
335+
mockHttpResponse(404, "Not Found");
336+
client.validateServerId("http://pdns", 8081, "apikey", "abc");
337+
}
338+
339+
@Test(expected = DnsAuthenticationException.class)
340+
public void testExecuteThrowsAuthError() throws Exception {
341+
mockHttpResponse(401, "Unauthorized");
342+
client.validateServerId("http://pdns", 8081, "apikey", "abc");
343+
}
344+
345+
@Test(expected = DnsConflictException.class)
346+
public void testExecuteThrowsConflictError() throws Exception {
347+
mockHttpResponse(409, "Conflict");
348+
client.validateServerId("http://pdns", 8081, "apikey", "abc");
349+
}
350+
351+
@Test(expected = DnsOperationException.class)
352+
public void testExecuteThrowsUnexpectedStatus() throws Exception {
353+
mockHttpResponse(500, "Server Error");
354+
client.validateServerId("http://pdns", 8081, "apikey", "abc");
355+
}
83356
}

0 commit comments

Comments
 (0)