mirror of https://github.com/apache/cloudstack.git
add unit tests
This commit is contained in:
parent
c6abed1702
commit
f1dcd00a9d
|
|
@ -18,13 +18,65 @@
|
|||
package org.apache.cloudstack.dns.powerdns;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.cloudstack.dns.exception.DnsOperationException;
|
||||
import org.apache.cloudstack.dns.exception.DnsAuthenticationException;
|
||||
import org.apache.cloudstack.dns.exception.DnsConflictException;
|
||||
import org.apache.cloudstack.dns.exception.DnsNotFoundException;
|
||||
import org.apache.http.StatusLine;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class PowerDnsClientTest {
|
||||
@InjectMocks
|
||||
PowerDnsClient client = new PowerDnsClient();
|
||||
|
||||
PowerDnsClient client;
|
||||
CloseableHttpClient httpClientMock;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
client = new PowerDnsClient();
|
||||
httpClientMock = mock(CloseableHttpClient.class);
|
||||
ReflectionTestUtils.setField(client, "httpClient", httpClientMock);
|
||||
}
|
||||
|
||||
private CloseableHttpResponse createResponse(int statusCode, String jsonBody) {
|
||||
CloseableHttpResponse responseMock = mock(CloseableHttpResponse.class);
|
||||
StatusLine statusLineMock = mock(StatusLine.class);
|
||||
when(responseMock.getStatusLine()).thenReturn(statusLineMock);
|
||||
when(statusLineMock.getStatusCode()).thenReturn(statusCode);
|
||||
|
||||
if (jsonBody != null) {
|
||||
when(responseMock.getEntity()).thenReturn(new StringEntity(jsonBody, StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
return responseMock;
|
||||
}
|
||||
|
||||
private void mockHttpResponse(int statusCode, String jsonBody) throws IOException {
|
||||
CloseableHttpResponse response = createResponse(statusCode, jsonBody);
|
||||
when(httpClientMock.execute(any(HttpUriRequest.class))).thenReturn(response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalizeApexRecord() {
|
||||
|
|
@ -80,4 +132,225 @@ public class PowerDnsClientTest {
|
|||
result = client.normalizeRecordName("www", "example.com.");
|
||||
assertEquals("www.example.com.", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDiscoverAuthoritativeServerIdSuccess() throws Exception {
|
||||
mockHttpResponse(200, "[{\"id\":\"localhost\", \"daemon_type\":\"authoritative\"}]");
|
||||
String result = client.discoverAuthoritativeServerId("http://pdns:8081", null, "apikey");
|
||||
assertEquals("localhost", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDiscoverAuthoritativeServerIdFallback() throws Exception {
|
||||
mockHttpResponse(200, "[{\"id\":\"server1\", \"daemon_type\":\"recursor\"}, {\"id\":\"server2\", \"daemon_type\":\"authoritative\"}]");
|
||||
String result = client.discoverAuthoritativeServerId("http://pdns", 8081, "apikey");
|
||||
assertEquals("server2", result);
|
||||
}
|
||||
|
||||
@Test(expected = DnsOperationException.class)
|
||||
public void testDiscoverAuthoritativeServerIdEmpty() throws Exception {
|
||||
mockHttpResponse(200, "[]");
|
||||
client.discoverAuthoritativeServerId("http://pdns", 8081, "apikey");
|
||||
}
|
||||
|
||||
@Test(expected = DnsOperationException.class)
|
||||
public void testDiscoverAuthoritativeServerIdNoAuthoritative() throws Exception {
|
||||
mockHttpResponse(200, "[{\"id\":\"server1\", \"daemon_type\":\"recursor\"}]");
|
||||
client.discoverAuthoritativeServerId("http://pdns", 8081, "apikey");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateServerIdSuccess() throws Exception {
|
||||
mockHttpResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"authoritative\"}");
|
||||
String result = client.validateServerId("http://pdns", 8081, "apikey", "abc");
|
||||
assertEquals("abc", result);
|
||||
}
|
||||
|
||||
@Test(expected = DnsOperationException.class)
|
||||
public void testValidateServerIdNotAuthoritative() throws Exception {
|
||||
mockHttpResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"recursor\"}");
|
||||
client.validateServerId("http://pdns", 8081, "apikey", "abc");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveServerIdWithExternalId() throws Exception {
|
||||
mockHttpResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"authoritative\"}");
|
||||
String result = client.resolveServerId("http://pdns", 8081, "apikey", "abc");
|
||||
assertEquals("abc", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveServerIdWithoutExternalId() throws Exception {
|
||||
mockHttpResponse(200, "[{\"id\":\"localhost\", \"daemon_type\":\"authoritative\"}]");
|
||||
String result = client.resolveServerId("http://pdns", 8081, "apikey", null);
|
||||
assertEquals("localhost", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateZone() throws Exception {
|
||||
when(httpClientMock.execute(any(HttpUriRequest.class))).thenAnswer(new Answer<CloseableHttpResponse>() {
|
||||
@Override
|
||||
public CloseableHttpResponse answer(InvocationOnMock invocation) {
|
||||
HttpUriRequest request = invocation.getArgument(0);
|
||||
if (request.getMethod().equals("GET")) {
|
||||
return createResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"authoritative\"}");
|
||||
}
|
||||
if (request.getMethod().equals("POST")) {
|
||||
return createResponse(201, "{\"id\":\"example.com.\"}");
|
||||
}
|
||||
return createResponse(500, null);
|
||||
}
|
||||
});
|
||||
|
||||
String result = client.createZone("http://pdns", 8081, "apikey", "abc", "example.com", "Native", false, Arrays.asList("ns1.com"));
|
||||
assertEquals("example.com.", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateZone() throws Exception {
|
||||
when(httpClientMock.execute(any(HttpUriRequest.class))).thenAnswer(new Answer<CloseableHttpResponse>() {
|
||||
@Override
|
||||
public CloseableHttpResponse answer(InvocationOnMock invocation) {
|
||||
HttpUriRequest request = invocation.getArgument(0);
|
||||
if (request.getMethod().equals("GET")) {
|
||||
return createResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"authoritative\"}");
|
||||
}
|
||||
if (request.getMethod().equals("PUT")) {
|
||||
return createResponse(204, null);
|
||||
}
|
||||
return createResponse(500, null);
|
||||
}
|
||||
});
|
||||
|
||||
client.updateZone("http://pdns", 8081, "apikey", "abc", "example.com", "Native", true, Arrays.asList("ns1.com"));
|
||||
// No exception means success
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteZone() throws Exception {
|
||||
when(httpClientMock.execute(any(HttpUriRequest.class))).thenAnswer(new Answer<CloseableHttpResponse>() {
|
||||
@Override
|
||||
public CloseableHttpResponse answer(InvocationOnMock invocation) {
|
||||
HttpUriRequest request = invocation.getArgument(0);
|
||||
if (request.getMethod().equals("GET")) {
|
||||
return createResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"authoritative\"}");
|
||||
}
|
||||
if (request.getMethod().equals("DELETE")) {
|
||||
return createResponse(204, null);
|
||||
}
|
||||
return createResponse(500, null);
|
||||
}
|
||||
});
|
||||
|
||||
client.deleteZone("http://pdns", 8081, "apikey", "abc", "example.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModifyRecord() throws Exception {
|
||||
when(httpClientMock.execute(any(HttpUriRequest.class))).thenAnswer(new Answer<CloseableHttpResponse>() {
|
||||
@Override
|
||||
public CloseableHttpResponse answer(InvocationOnMock invocation) {
|
||||
HttpUriRequest request = invocation.getArgument(0);
|
||||
if (request.getMethod().equals("GET")) {
|
||||
return createResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"authoritative\"}");
|
||||
}
|
||||
if (request.getMethod().equals("PATCH")) {
|
||||
return createResponse(204, null);
|
||||
}
|
||||
return createResponse(500, null);
|
||||
}
|
||||
});
|
||||
|
||||
String result = client.modifyRecord("http://pdns", 8081, "apikey", "abc", "example.com", "www", "A", 300, Arrays.asList("1.2.3.4"), "REPLACE");
|
||||
assertEquals("www.example.com", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModifyRecordApex() throws Exception {
|
||||
when(httpClientMock.execute(any(HttpUriRequest.class))).thenAnswer(new Answer<CloseableHttpResponse>() {
|
||||
@Override
|
||||
public CloseableHttpResponse answer(InvocationOnMock invocation) {
|
||||
HttpUriRequest request = invocation.getArgument(0);
|
||||
if (request.getMethod().equals("GET")) {
|
||||
return createResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"authoritative\"}");
|
||||
}
|
||||
if (request.getMethod().equals("PATCH")) {
|
||||
return createResponse(204, null);
|
||||
}
|
||||
return createResponse(500, null);
|
||||
}
|
||||
});
|
||||
|
||||
String result = client.modifyRecord("http://pdns", 8081, "apikey", "abc", "example.com", "@", "A", 300, Arrays.asList("1.2.3.4"), "REPLACE");
|
||||
assertEquals("example.com", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListRecords() throws Exception {
|
||||
when(httpClientMock.execute(any(HttpUriRequest.class))).thenAnswer(new Answer<CloseableHttpResponse>() {
|
||||
@Override
|
||||
public CloseableHttpResponse answer(InvocationOnMock invocation) {
|
||||
HttpUriRequest request = invocation.getArgument(0);
|
||||
// validateServerId uses /servers/abc
|
||||
// listRecords uses /servers/abc/zones/example.com.
|
||||
if (request.getURI().getPath().endsWith("abc")) {
|
||||
return createResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"authoritative\"}");
|
||||
}
|
||||
if (request.getURI().getPath().endsWith("example.com.")) {
|
||||
return createResponse(200, "{\"rrsets\":[{\"name\":\"www.example.com.\",\"type\":\"A\"}]}");
|
||||
}
|
||||
return createResponse(500, null);
|
||||
}
|
||||
});
|
||||
|
||||
Iterable<JsonNode> records = client.listRecords("http://pdns", 8081, "apikey", "abc", "example.com");
|
||||
assertNotNull(records);
|
||||
assertTrue(records.iterator().hasNext());
|
||||
assertEquals("www.example.com.", records.iterator().next().path("name").asText());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListRecordsEmpty() throws Exception {
|
||||
when(httpClientMock.execute(any(HttpUriRequest.class))).thenAnswer(new Answer<CloseableHttpResponse>() {
|
||||
@Override
|
||||
public CloseableHttpResponse answer(InvocationOnMock invocation) {
|
||||
HttpUriRequest request = invocation.getArgument(0);
|
||||
if (request.getURI().getPath().endsWith("abc")) {
|
||||
return createResponse(200, "{\"id\":\"abc\", \"daemon_type\":\"authoritative\"}");
|
||||
}
|
||||
if (request.getURI().getPath().endsWith("example.com.")) {
|
||||
return createResponse(200, "{}");
|
||||
}
|
||||
return createResponse(500, null);
|
||||
}
|
||||
});
|
||||
|
||||
Iterable<JsonNode> records = client.listRecords("http://pdns", 8081, "apikey", "abc", "example.com");
|
||||
assertNotNull(records);
|
||||
assertTrue(!records.iterator().hasNext());
|
||||
}
|
||||
|
||||
@Test(expected = DnsNotFoundException.class)
|
||||
public void testExecuteThrowsNotFound() throws Exception {
|
||||
mockHttpResponse(404, "Not Found");
|
||||
client.validateServerId("http://pdns", 8081, "apikey", "abc");
|
||||
}
|
||||
|
||||
@Test(expected = DnsAuthenticationException.class)
|
||||
public void testExecuteThrowsAuthError() throws Exception {
|
||||
mockHttpResponse(401, "Unauthorized");
|
||||
client.validateServerId("http://pdns", 8081, "apikey", "abc");
|
||||
}
|
||||
|
||||
@Test(expected = DnsConflictException.class)
|
||||
public void testExecuteThrowsConflictError() throws Exception {
|
||||
mockHttpResponse(409, "Conflict");
|
||||
client.validateServerId("http://pdns", 8081, "apikey", "abc");
|
||||
}
|
||||
|
||||
@Test(expected = DnsOperationException.class)
|
||||
public void testExecuteThrowsUnexpectedStatus() throws Exception {
|
||||
mockHttpResponse(500, "Server Error");
|
||||
client.validateServerId("http://pdns", 8081, "apikey", "abc");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,391 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.dns.powerdns;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyList;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.dns.DnsRecord;
|
||||
import org.apache.cloudstack.dns.DnsRecord.RecordType;
|
||||
import org.apache.cloudstack.dns.DnsServer;
|
||||
import org.apache.cloudstack.dns.DnsZone;
|
||||
import org.apache.cloudstack.dns.DnsProviderType;
|
||||
import org.apache.cloudstack.dns.exception.DnsProviderException;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class PowerDnsProviderTest {
|
||||
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
|
||||
private PowerDnsProvider provider;
|
||||
private PowerDnsClient clientMock;
|
||||
private DnsServer serverMock;
|
||||
private DnsZone zoneMock;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
provider = new PowerDnsProvider();
|
||||
clientMock = mock(PowerDnsClient.class);
|
||||
serverMock = mock(DnsServer.class);
|
||||
zoneMock = mock(DnsZone.class);
|
||||
ReflectionTestUtils.setField(provider, "client", clientMock);
|
||||
|
||||
when(serverMock.getUrl()).thenReturn("http://pdns:8081");
|
||||
when(serverMock.getApiKey()).thenReturn("secret");
|
||||
when(serverMock.getPort()).thenReturn(8081);
|
||||
when(serverMock.getExternalServerId()).thenReturn("localhost");
|
||||
when(serverMock.getNameServers()).thenReturn(Arrays.asList("ns1.example.com"));
|
||||
|
||||
when(zoneMock.getName()).thenReturn("example.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetProviderType() {
|
||||
assertEquals(DnsProviderType.PowerDNS, provider.getProviderType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigureCreatesClientWhenNull() {
|
||||
PowerDnsProvider freshProvider = new PowerDnsProvider();
|
||||
boolean result = freshProvider.configure("test", new HashMap<>());
|
||||
assertTrue(result);
|
||||
assertNotNull(ReflectionTestUtils.getField(freshProvider, "client"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigureDoesNotReplaceExistingClient() {
|
||||
PowerDnsClient existingClient = mock(PowerDnsClient.class);
|
||||
ReflectionTestUtils.setField(provider, "client", existingClient);
|
||||
|
||||
boolean result = provider.configure("test", new HashMap<>());
|
||||
|
||||
assertTrue(result);
|
||||
assertEquals(existingClient, ReflectionTestUtils.getField(provider, "client"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStopClosesClient() {
|
||||
boolean result = provider.stop();
|
||||
assertTrue(result);
|
||||
verify(clientMock, times(1)).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStopWithNullClientSucceeds() {
|
||||
ReflectionTestUtils.setField(provider, "client", null);
|
||||
boolean result = provider.stop();
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testValidateServerFieldsNullUrl() {
|
||||
when(serverMock.getUrl()).thenReturn(null);
|
||||
provider.validateRequiredServerFields(serverMock);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testValidateServerFieldsBlankUrl() {
|
||||
when(serverMock.getUrl()).thenReturn(" ");
|
||||
provider.validateRequiredServerFields(serverMock);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testValidateServerFieldsNullApiKey() {
|
||||
when(serverMock.getApiKey()).thenReturn(null);
|
||||
provider.validateRequiredServerFields(serverMock);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testValidateServerFieldsBlankApiKey() {
|
||||
when(serverMock.getApiKey()).thenReturn("");
|
||||
provider.validateRequiredServerFields(serverMock);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testValidateServerAndZoneFieldsBlankZoneName() {
|
||||
when(zoneMock.getName()).thenReturn(" ");
|
||||
provider.validateRequiredServerAndZoneFields(serverMock, zoneMock);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testValidateServerAndZoneFieldsNullZoneName() {
|
||||
when(zoneMock.getName()).thenReturn(null);
|
||||
provider.validateRequiredServerAndZoneFields(serverMock, zoneMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDelegatesToClient() throws DnsProviderException {
|
||||
when(clientMock.validateServerId(anyString(), anyInt(), anyString(), anyString())).thenReturn("localhost");
|
||||
provider.validate(serverMock);
|
||||
verify(clientMock).validateServerId("http://pdns:8081", 8081, "secret", "localhost");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testValidateThrowsWhenServerUrlBlank() throws DnsProviderException {
|
||||
when(serverMock.getUrl()).thenReturn("");
|
||||
provider.validate(serverMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateAndResolveServer() throws Exception {
|
||||
when(clientMock.resolveServerId(anyString(), anyInt(), anyString(), anyString())).thenReturn("localhost");
|
||||
String result = provider.validateAndResolveServer(serverMock);
|
||||
assertEquals("localhost", result);
|
||||
verify(clientMock).resolveServerId("http://pdns:8081", 8081, "secret", "localhost");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testValidateAndResolveServerThrowsWhenUrlBlank() throws Exception {
|
||||
when(serverMock.getUrl()).thenReturn(null);
|
||||
provider.validateAndResolveServer(serverMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProvisionZoneDelegatesToClient() throws DnsProviderException {
|
||||
when(clientMock.createZone(anyString(), anyInt(), anyString(), anyString(), anyString(), anyString(), eq(false), anyList())).thenReturn("example.com.");
|
||||
String zoneId = provider.provisionZone(serverMock, zoneMock);
|
||||
assertEquals("example.com.", zoneId);
|
||||
verify(clientMock).createZone("http://pdns:8081", 8081, "secret", "localhost", "example.com",
|
||||
"Native", false, Arrays.asList("ns1.example.com"));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testProvisionZoneThrowsWhenZoneNameBlank() throws DnsProviderException {
|
||||
when(zoneMock.getName()).thenReturn(null);
|
||||
provider.provisionZone(serverMock, zoneMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteZoneDelegatesToClient() throws DnsProviderException {
|
||||
provider.deleteZone(serverMock, zoneMock);
|
||||
verify(clientMock).deleteZone("http://pdns:8081", 8081, "secret", "localhost", "example.com");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testDeleteZoneThrowsWhenZoneNameBlank() throws DnsProviderException {
|
||||
when(zoneMock.getName()).thenReturn("");
|
||||
provider.deleteZone(serverMock, zoneMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateZoneDelegatesToClient() throws DnsProviderException {
|
||||
provider.updateZone(serverMock, zoneMock);
|
||||
verify(clientMock).updateZone("http://pdns:8081", 8081, "secret", "localhost", "example.com",
|
||||
"Native", false, Arrays.asList("ns1.example.com"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddRecordDelegatesToClient() throws DnsProviderException {
|
||||
DnsRecord record = new DnsRecord("www", RecordType.A, Arrays.asList("1.2.3.4"), 300);
|
||||
when(clientMock.modifyRecord(anyString(), anyInt(), anyString(), anyString(), anyString(),
|
||||
anyString(), anyString(), anyLong(), anyList(), anyString())).thenReturn("www.example.com");
|
||||
|
||||
String result = provider.addRecord(serverMock, zoneMock, record);
|
||||
|
||||
assertEquals("www.example.com", result);
|
||||
verify(clientMock).modifyRecord("http://pdns:8081", 8081, "secret", "localhost", "example.com",
|
||||
"www", "A", 300L, Arrays.asList("1.2.3.4"), "REPLACE");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAddRecordThrowsWhenServerUrlBlank() throws DnsProviderException {
|
||||
when(serverMock.getUrl()).thenReturn("");
|
||||
DnsRecord record = new DnsRecord("www", RecordType.A, Arrays.asList("1.2.3.4"), 300);
|
||||
provider.addRecord(serverMock, zoneMock, record);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateRecordDelegatesToAddRecord() throws DnsProviderException {
|
||||
DnsRecord record = new DnsRecord("mail", RecordType.MX, Arrays.asList("10 mail.example.com"), 300);
|
||||
when(clientMock.modifyRecord(anyString(), anyInt(), anyString(), anyString(), anyString(),
|
||||
anyString(), anyString(), anyLong(), anyList(), anyString())).thenReturn("mail.example.com");
|
||||
|
||||
String result = provider.updateRecord(serverMock, zoneMock, record);
|
||||
|
||||
assertEquals("mail.example.com", result);
|
||||
verify(clientMock).modifyRecord(anyString(), anyInt(), anyString(), anyString(), anyString(),
|
||||
eq("mail"), eq("MX"), eq(300L), eq(Arrays.asList("10 mail.example.com")), eq("REPLACE"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteRecordDelegatesToClientWithDeleteChangeType() throws DnsProviderException {
|
||||
DnsRecord record = new DnsRecord("old", RecordType.CNAME, Arrays.asList("target.com"), 600);
|
||||
when(clientMock.modifyRecord(anyString(), anyInt(), anyString(), anyString(), anyString(),
|
||||
anyString(), anyString(), anyLong(), anyList(), anyString())).thenReturn("old.example.com");
|
||||
|
||||
String result = provider.deleteRecord(serverMock, zoneMock, record);
|
||||
|
||||
assertEquals("old.example.com", result);
|
||||
verify(clientMock).modifyRecord(anyString(), anyInt(), anyString(), anyString(), anyString(),
|
||||
eq("old"), eq("CNAME"), eq(600L), eq(Arrays.asList("target.com")), eq("DELETE"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyRecordPassesChangeTypeToClient() throws DnsProviderException {
|
||||
DnsRecord record = new DnsRecord("txt", RecordType.TXT, Arrays.asList("v=spf1 include:example.com ~all"), 3600);
|
||||
when(clientMock.modifyRecord(anyString(), anyInt(), anyString(), anyString(), anyString(),
|
||||
anyString(), anyString(), anyLong(), anyList(), anyString())).thenReturn("txt.example.com");
|
||||
|
||||
provider.applyRecord("http://pdns:8081", 8081, "secret", "localhost", "example.com",
|
||||
record, PowerDnsProvider.ChangeType.REPLACE);
|
||||
|
||||
verify(clientMock).modifyRecord("http://pdns:8081", 8081, "secret", "localhost", "example.com",
|
||||
"txt", "TXT", 3600L, Arrays.asList("v=spf1 include:example.com ~all"), "REPLACE");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListRecordsParsesRrsets() throws DnsProviderException {
|
||||
ObjectNode aRecord = MAPPER.createObjectNode();
|
||||
aRecord.put("name", "www.example.com.");
|
||||
aRecord.put("type", "A");
|
||||
aRecord.put("ttl", 300);
|
||||
ArrayNode records = aRecord.putArray("records");
|
||||
records.addObject().put("content", "1.2.3.4");
|
||||
|
||||
ObjectNode mxRecord = MAPPER.createObjectNode();
|
||||
mxRecord.put("name", "example.com.");
|
||||
mxRecord.put("type", "MX");
|
||||
mxRecord.put("ttl", 600);
|
||||
ArrayNode mxRecords = mxRecord.putArray("records");
|
||||
mxRecords.addObject().put("content", "10 mail.example.com");
|
||||
|
||||
when(clientMock.listRecords(anyString(), anyInt(), anyString(), anyString(), anyString()))
|
||||
.thenReturn(Arrays.asList(aRecord, mxRecord));
|
||||
|
||||
List<DnsRecord> result = provider.listRecords(serverMock, zoneMock);
|
||||
|
||||
assertEquals(2, result.size());
|
||||
|
||||
DnsRecord first = result.get(0);
|
||||
assertEquals("www.example.com.", first.getName());
|
||||
assertEquals(RecordType.A, first.getType());
|
||||
assertEquals(300, first.getTtl());
|
||||
assertEquals(Arrays.asList("1.2.3.4"), first.getContents());
|
||||
|
||||
DnsRecord second = result.get(1);
|
||||
assertEquals("example.com.", second.getName());
|
||||
assertEquals(RecordType.MX, second.getType());
|
||||
assertEquals(600, second.getTtl());
|
||||
assertEquals(Arrays.asList("10 mail.example.com"), second.getContents());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListRecordsSkipsSoaRecords() throws DnsProviderException {
|
||||
ObjectNode soaRecord = MAPPER.createObjectNode();
|
||||
soaRecord.put("name", "example.com.");
|
||||
soaRecord.put("type", "SOA");
|
||||
soaRecord.put("ttl", 3600);
|
||||
soaRecord.putArray("records").addObject().put("content", "ns1.example.com. admin.example.com. ...");
|
||||
|
||||
when(clientMock.listRecords(anyString(), anyInt(), anyString(), anyString(), anyString()))
|
||||
.thenReturn(Collections.singletonList(soaRecord));
|
||||
|
||||
List<DnsRecord> result = provider.listRecords(serverMock, zoneMock);
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListRecordsSkipsUnknownRecordTypes() throws DnsProviderException {
|
||||
ObjectNode unknownRecord = MAPPER.createObjectNode();
|
||||
unknownRecord.put("name", "test.example.com.");
|
||||
unknownRecord.put("type", "UNKNOWNTYPE");
|
||||
unknownRecord.put("ttl", 300);
|
||||
unknownRecord.putArray("records").addObject().put("content", "some-data");
|
||||
|
||||
when(clientMock.listRecords(anyString(), anyInt(), anyString(), anyString(), anyString()))
|
||||
.thenReturn(Collections.singletonList(unknownRecord));
|
||||
|
||||
List<DnsRecord> result = provider.listRecords(serverMock, zoneMock);
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListRecordsIgnoresEmptyContentEntries() throws DnsProviderException {
|
||||
ObjectNode aRecord = MAPPER.createObjectNode();
|
||||
aRecord.put("name", "host.example.com.");
|
||||
aRecord.put("type", "A");
|
||||
aRecord.put("ttl", 300);
|
||||
ArrayNode records = aRecord.putArray("records");
|
||||
records.addObject().put("content", "");
|
||||
records.addObject().put("content", "5.6.7.8");
|
||||
|
||||
when(clientMock.listRecords(anyString(), anyInt(), anyString(), anyString(), anyString()))
|
||||
.thenReturn(Collections.singletonList(aRecord));
|
||||
|
||||
List<DnsRecord> result = provider.listRecords(serverMock, zoneMock);
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(Collections.singletonList("5.6.7.8"), result.get(0).getContents());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListRecordsReturnsEmptyListWhenClientReturnsEmpty() throws DnsProviderException {
|
||||
when(clientMock.listRecords(anyString(), anyInt(), anyString(), anyString(), anyString()))
|
||||
.thenReturn(Collections.emptyList());
|
||||
|
||||
List<DnsRecord> result = provider.listRecords(serverMock, zoneMock);
|
||||
assertNotNull(result);
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
@Test(expected = DnsProviderException.class)
|
||||
public void testListRecordsPropagatesClientException() throws DnsProviderException {
|
||||
when(clientMock.listRecords(anyString(), anyInt(), anyString(), anyString(), anyString()))
|
||||
.thenThrow(mock(DnsProviderException.class));
|
||||
|
||||
provider.listRecords(serverMock, zoneMock);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testListRecordsThrowsWhenZoneNameBlank() throws DnsProviderException {
|
||||
when(zoneMock.getName()).thenReturn("");
|
||||
provider.listRecords(serverMock, zoneMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChangeTypeValues() {
|
||||
assertEquals("REPLACE", PowerDnsProvider.ChangeType.REPLACE.name());
|
||||
assertEquals("DELETE", PowerDnsProvider.ChangeType.DELETE.name());
|
||||
}
|
||||
}
|
||||
|
|
@ -34,7 +34,6 @@ import org.apache.cloudstack.api.InternalIdentity;
|
|||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.framework.events.EventDistributor;
|
||||
import org.apache.cloudstack.framework.messagebus.MessageBus;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
|
@ -86,8 +85,6 @@ public class ActionEventUtils {
|
|||
EntityManager entityMgr;
|
||||
@Inject
|
||||
ConfigurationDao configDao;
|
||||
@Inject
|
||||
MessageBus messageBus;
|
||||
|
||||
public ActionEventUtils() {
|
||||
}
|
||||
|
|
@ -100,7 +97,6 @@ public class ActionEventUtils {
|
|||
s_projectDao = projectDao;
|
||||
s_entityMgr = entityMgr;
|
||||
s_configDao = configDao;
|
||||
messageBus = messageBus;
|
||||
}
|
||||
|
||||
public static Long onActionEvent(Long userId, Long accountId, Long domainId, String type, String description, Long resourceId, String resourceType) {
|
||||
|
|
|
|||
|
|
@ -1,196 +0,0 @@
|
|||
//
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
|
||||
package org.apache.cloudstack.dns;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.framework.events.Event;
|
||||
import org.apache.cloudstack.framework.events.EventBus;
|
||||
import org.apache.cloudstack.framework.events.EventBusException;
|
||||
import org.apache.cloudstack.framework.events.EventSubscriber;
|
||||
import org.apache.cloudstack.framework.events.EventTopic;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.vm.Nic;
|
||||
import com.cloud.vm.NicVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import com.cloud.vm.dao.NicDetailsDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
@Component
|
||||
public class DnsVmLifecycleListener extends ManagerBase implements EventSubscriber {
|
||||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||
|
||||
@Inject
|
||||
private EventBus eventBus = null;
|
||||
|
||||
@Inject
|
||||
VMInstanceDao vmInstanceDao;
|
||||
@Inject
|
||||
NetworkDao networkDao;
|
||||
@Inject
|
||||
NicDao nicDao;
|
||||
@Inject
|
||||
DnsProviderManager providerManager;
|
||||
@Inject
|
||||
NicDetailsDao nicDetailsDao;
|
||||
|
||||
@Override
|
||||
public boolean configure(final String name, final Map<String, Object> params) {
|
||||
if (eventBus == null) {
|
||||
logger.info("EventBus is not available; DNS Instance lifecycle listener will not subscribe to events");
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
eventBus.subscribe(new EventTopic(null, EventTypes.EVENT_VM_CREATE, null, null, null), this);
|
||||
eventBus.subscribe(new EventTopic(null, EventTypes.EVENT_VM_START, null, null, null), this);
|
||||
eventBus.subscribe(new EventTopic(null, EventTypes.EVENT_VM_STOP, null, null, null), this);
|
||||
eventBus.subscribe(new EventTopic(null, EventTypes.EVENT_VM_DESTROY, null, null, null), this);
|
||||
eventBus.subscribe(new EventTopic(null, EventTypes.EVENT_NIC_CREATE, null, null, null), this);
|
||||
eventBus.subscribe(new EventTopic(null, EventTypes.EVENT_NIC_DELETE, null, null, null), this);
|
||||
eventBus.subscribe(new EventTopic(null, EventTypes.EVENT_DNS_RECORD_DELETE, null, null, null), this);
|
||||
} catch (EventBusException ex) {
|
||||
logger.error("Failed to subscribe DnsVmLifecycleListener to EventBus", ex);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(Event event) {
|
||||
JsonNode descJson = parseEventDescription(event);
|
||||
if (!isEventCompleted(descJson)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String eventType = event.getEventType();
|
||||
String resourceUuid = event.getResourceUUID();
|
||||
try {
|
||||
switch (eventType) {
|
||||
case EventTypes.EVENT_VM_CREATE:
|
||||
case EventTypes.EVENT_VM_START:
|
||||
handleVmEvent(resourceUuid, true);
|
||||
break;
|
||||
case EventTypes.EVENT_VM_STOP:
|
||||
case EventTypes.EVENT_VM_DESTROY:
|
||||
handleVmEvent(resourceUuid, false);
|
||||
break;
|
||||
case EventTypes.EVENT_NIC_CREATE:
|
||||
handleNicEvent(descJson, true);
|
||||
break;
|
||||
case EventTypes.EVENT_NIC_DELETE:
|
||||
handleNicEvent(descJson, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
logger.error("Failed to process DNS lifecycle event: type={}, resourceUuid={}",
|
||||
eventType, event.getResourceUUID(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleNicEvent(JsonNode eventDesc, boolean isAddDnsRecord) {
|
||||
JsonNode nicUuid = eventDesc.get("Nic");
|
||||
JsonNode vmUuid = eventDesc.get("VirtualMachine");
|
||||
if (nicUuid == null || nicUuid.isNull() || vmUuid == null || vmUuid.isNull()) {
|
||||
logger.warn("Event has missing data to work on: {}", eventDesc);
|
||||
return;
|
||||
}
|
||||
VMInstanceVO vmInstanceVO = vmInstanceDao.findByUuid(vmUuid.asText());
|
||||
if (vmInstanceVO == null) {
|
||||
logger.error("Unable to find Instance with ID: {}", vmUuid);
|
||||
return;
|
||||
}
|
||||
Nic nic = nicDao.findByUuidIncludingRemoved(nicUuid.asText());
|
||||
if (nic == null) {
|
||||
logger.error("NIC is not found for the ID: {}", nicUuid);
|
||||
return;
|
||||
}
|
||||
Network network = networkDao.findById(nic.getNetworkId());
|
||||
if (network == null || !Network.GuestType.Shared.equals(network.getGuestType())) {
|
||||
logger.warn("Network is not eligible for DNS record registration");
|
||||
return;
|
||||
}
|
||||
processEventForDnsRecord(vmInstanceVO, network, nic, isAddDnsRecord);
|
||||
}
|
||||
|
||||
private void handleVmEvent(String vmUuid, boolean isAddDnsRecord) {
|
||||
VMInstanceVO vmInstanceVO = vmInstanceDao.findByUuidIncludingRemoved(vmUuid);
|
||||
if (vmInstanceVO == null) {
|
||||
logger.error("Unable to find Instance with ID: {}", vmUuid);
|
||||
return;
|
||||
}
|
||||
List<NicVO> vmNics = nicDao.listByVmIdIncludingRemoved(vmInstanceVO.getId());
|
||||
for (NicVO nic : vmNics) {
|
||||
Network network = networkDao.findById(nic.getNetworkId());
|
||||
if (network == null || !Network.GuestType.Shared.equals(network.getGuestType())) {
|
||||
continue;
|
||||
}
|
||||
processEventForDnsRecord(vmInstanceVO, network, nic, isAddDnsRecord);
|
||||
}
|
||||
}
|
||||
|
||||
void processEventForDnsRecord(VMInstanceVO vmInstanceVO, Network network, Nic nic, boolean isAddDnsRecord) {
|
||||
if (isAddDnsRecord) {
|
||||
providerManager.addDnsRecordForVM(vmInstanceVO, network, nic);
|
||||
} else {
|
||||
providerManager.deleteDnsRecordForVM(vmInstanceVO, network, nic);
|
||||
}
|
||||
}
|
||||
|
||||
private JsonNode parseEventDescription(Event event) {
|
||||
String rawDescription = event.getDescription();
|
||||
if (StringUtils.isBlank(rawDescription)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return OBJECT_MAPPER.readTree(rawDescription);
|
||||
} catch (Exception ex) {
|
||||
logger.warn("parseEventDescription: failed to parse description for event [{}]: {}",
|
||||
event.getEventType(), ex.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEventCompleted(JsonNode descJson) {
|
||||
if (descJson == null) {
|
||||
return false;
|
||||
}
|
||||
JsonNode statusNode = descJson.get(ApiConstants.STATUS);
|
||||
if (statusNode == null || statusNode.isNull()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.debug("Processing Event: {}", descJson);
|
||||
return ApiConstants.COMPLETED.equalsIgnoreCase(statusNode.asText());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,892 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.dns;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.command.user.dns.CreateDnsZoneCmd;
|
||||
import org.apache.cloudstack.api.command.user.dns.DeleteDnsServerCmd;
|
||||
|
||||
import org.apache.cloudstack.api.command.user.dns.DisassociateDnsZoneFromNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.dns.ListDnsRecordsCmd;
|
||||
import org.apache.cloudstack.api.command.user.dns.UpdateDnsZoneCmd;
|
||||
import org.apache.cloudstack.api.response.DnsRecordResponse;
|
||||
import org.apache.cloudstack.api.response.DnsServerResponse;
|
||||
import org.apache.cloudstack.api.response.DnsZoneNetworkMapResponse;
|
||||
import org.apache.cloudstack.api.response.DnsZoneResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.dns.dao.DnsServerDao;
|
||||
import org.apache.cloudstack.dns.dao.DnsServerJoinDao;
|
||||
import org.apache.cloudstack.dns.dao.DnsZoneDao;
|
||||
import org.apache.cloudstack.dns.dao.DnsZoneJoinDao;
|
||||
import org.apache.cloudstack.dns.dao.DnsZoneNetworkMapDao;
|
||||
import org.apache.cloudstack.dns.exception.DnsConflictException;
|
||||
import org.apache.cloudstack.dns.exception.DnsNotFoundException;
|
||||
import org.apache.cloudstack.dns.exception.DnsProviderException;
|
||||
import org.apache.cloudstack.dns.exception.DnsTransportException;
|
||||
import org.apache.cloudstack.dns.vo.DnsServerJoinVO;
|
||||
import org.apache.cloudstack.dns.vo.DnsServerVO;
|
||||
import org.apache.cloudstack.dns.vo.DnsZoneJoinVO;
|
||||
import org.apache.cloudstack.dns.vo.DnsZoneNetworkMapVO;
|
||||
import org.apache.cloudstack.dns.vo.DnsZoneVO;
|
||||
import org.apache.cloudstack.framework.messagebus.MessageBus;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.db.TransactionCallback;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.NicDetailVO;
|
||||
import com.cloud.vm.NicVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import com.cloud.vm.dao.NicDetailsDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DnsProviderManagerImplTest {
|
||||
|
||||
private static final long ACCOUNT_ID = 1L;
|
||||
private static final long DOMAIN_ID = 10L;
|
||||
private static final long SERVER_ID = 100L;
|
||||
private static final long ZONE_ID = 200L;
|
||||
private static final long NETWORK_ID = 300L;
|
||||
|
||||
@InjectMocks
|
||||
DnsProviderManagerImpl manager;
|
||||
|
||||
@Mock AccountManager accountMgr;
|
||||
@Mock DnsServerDao dnsServerDao;
|
||||
@Mock DnsZoneDao dnsZoneDao;
|
||||
@Mock DnsZoneJoinDao dnsZoneJoinDao;
|
||||
@Mock DnsServerJoinDao dnsServerJoinDao;
|
||||
@Mock DnsZoneNetworkMapDao dnsZoneNetworkMapDao;
|
||||
@Mock NetworkDao networkDao;
|
||||
@Mock DomainDao domainDao;
|
||||
@Mock NicDao nicDao;
|
||||
@Mock NicDetailsDao nicDetailsDao;
|
||||
@Mock MessageBus messageBus;
|
||||
@Mock VMInstanceDao vmInstanceDao;
|
||||
@Mock DnsProvider dnsProviderMock;
|
||||
@Mock Account callerMock;
|
||||
|
||||
private MockedStatic<CallContext> callContextMocked;
|
||||
private CallContext callContextMock;
|
||||
|
||||
// Support VOs
|
||||
private DnsServerVO serverVO;
|
||||
private DnsZoneVO zoneVO;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
callContextMocked = Mockito.mockStatic(CallContext.class);
|
||||
callContextMock = mock(CallContext.class);
|
||||
callContextMocked.when(CallContext::current).thenReturn(callContextMock);
|
||||
when(callContextMock.getCallingAccount()).thenReturn(callerMock);
|
||||
when(callerMock.getId()).thenReturn(ACCOUNT_ID);
|
||||
when(callerMock.getDomainId()).thenReturn(DOMAIN_ID);
|
||||
|
||||
serverVO = Mockito.spy(new DnsServerVO("test-server", "http://pdns:8081", 8081, "localhost",
|
||||
DnsProviderType.PowerDNS, null, "apikey", false, null,
|
||||
Collections.singletonList("ns1.example.com"), ACCOUNT_ID, DOMAIN_ID));
|
||||
Mockito.lenient().doReturn(SERVER_ID).when(serverVO).getId();
|
||||
|
||||
zoneVO = Mockito.spy(new DnsZoneVO("example.com", DnsZone.ZoneType.Public, SERVER_ID, ACCOUNT_ID, DOMAIN_ID, "Test zone"));
|
||||
Mockito.lenient().doReturn(ZONE_ID).when(zoneVO).getId();
|
||||
|
||||
when(dnsProviderMock.getProviderType()).thenReturn(DnsProviderType.PowerDNS);
|
||||
manager.setDnsProviders(Collections.singletonList(dnsProviderMock));
|
||||
|
||||
doNothing().when(accountMgr).checkAccess(any(Account.class), nullable(org.apache.cloudstack.acl.SecurityChecker.AccessType.class), eq(true), any());
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
callContextMocked.close();
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testGetProviderByTypeNull() {
|
||||
// Setting providers to empty to force lookup failure
|
||||
manager.setDnsProviders(Collections.emptyList());
|
||||
// Trigger via provisionDnsZone which calls getProviderByType
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(serverVO);
|
||||
manager.provisionDnsZone(ZONE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListProviderNamesReturnsList() {
|
||||
List<String> names = manager.listProviderNames();
|
||||
assertEquals(1, names.size());
|
||||
assertEquals("PowerDNS", names.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListProviderNamesWithNullProviders() {
|
||||
manager.setDnsProviders(null);
|
||||
List<String> names = manager.listProviderNames();
|
||||
assertTrue(names.isEmpty());
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testAllocateDnsZoneBlankName() {
|
||||
CreateDnsZoneCmd cmd = mock(CreateDnsZoneCmd.class);
|
||||
when(cmd.getName()).thenReturn(" ");
|
||||
manager.allocateDnsZone(cmd);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testAllocateDnsZoneServerNotFound() {
|
||||
CreateDnsZoneCmd cmd = mock(CreateDnsZoneCmd.class);
|
||||
when(cmd.getName()).thenReturn("example.com");
|
||||
when(cmd.getDnsServerId()).thenReturn(SERVER_ID);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(null);
|
||||
manager.allocateDnsZone(cmd);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testAllocateDnsZoneAlreadyExists() {
|
||||
CreateDnsZoneCmd cmd = mock(CreateDnsZoneCmd.class);
|
||||
when(cmd.getName()).thenReturn("example.com");
|
||||
when(cmd.getDnsServerId()).thenReturn(SERVER_ID);
|
||||
when(cmd.getType()).thenReturn(DnsZone.ZoneType.Public);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(serverVO);
|
||||
Mockito.doReturn(SERVER_ID).when(serverVO).getId();
|
||||
Mockito.doReturn(ACCOUNT_ID).when(serverVO).getAccountId();
|
||||
when(dnsZoneDao.findByNameServerAndType(anyString(), anyLong(), any())).thenReturn(zoneVO);
|
||||
manager.allocateDnsZone(cmd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateDnsZoneOwnerSuccess() {
|
||||
CreateDnsZoneCmd cmd = mock(CreateDnsZoneCmd.class);
|
||||
when(cmd.getName()).thenReturn("example.com");
|
||||
when(cmd.getDnsServerId()).thenReturn(SERVER_ID);
|
||||
when(cmd.getType()).thenReturn(DnsZone.ZoneType.Public);
|
||||
when(cmd.getDescription()).thenReturn("desc");
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(serverVO);
|
||||
Mockito.doReturn(SERVER_ID).when(serverVO).getId();
|
||||
Mockito.doReturn(ACCOUNT_ID).when(serverVO).getAccountId();
|
||||
when(dnsZoneDao.findByNameServerAndType(anyString(), anyLong(), any())).thenReturn(null);
|
||||
when(dnsZoneDao.persist(any(DnsZoneVO.class))).thenReturn(zoneVO);
|
||||
DnsZone result = manager.allocateDnsZone(cmd);
|
||||
assertNotNull(result);
|
||||
}
|
||||
|
||||
@Test(expected = PermissionDeniedException.class)
|
||||
public void testAllocateDnsZoneNonOwnerPrivateServer() {
|
||||
CreateDnsZoneCmd cmd = mock(CreateDnsZoneCmd.class);
|
||||
when(cmd.getName()).thenReturn("tenant.com");
|
||||
when(cmd.getDnsServerId()).thenReturn(SERVER_ID);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(serverVO);
|
||||
Mockito.doReturn(ACCOUNT_ID + 99).when(serverVO).getAccountId(); // different owner
|
||||
|
||||
manager.allocateDnsZone(cmd);
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testProvisionDnsZoneNotFound() {
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(null);
|
||||
manager.provisionDnsZone(ZONE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProvisionDnsZoneSuccess() throws Exception {
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(serverVO);
|
||||
when(dnsProviderMock.provisionZone(any(), any())).thenReturn("example.com.");
|
||||
when(dnsZoneDao.update(anyLong(), any())).thenReturn(true);
|
||||
DnsZone result = manager.provisionDnsZone(ZONE_ID);
|
||||
assertNotNull(result);
|
||||
verify(dnsProviderMock).provisionZone(serverVO, zoneVO);
|
||||
verify(dnsZoneDao).update(anyLong(), any());
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testProvisionDnsZoneConflictException() throws Exception {
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(serverVO);
|
||||
when(dnsProviderMock.provisionZone(any(), any())).thenThrow(new DnsConflictException("conflict"));
|
||||
manager.provisionDnsZone(ZONE_ID);
|
||||
verify(dnsZoneDao).remove(ZONE_ID);
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testProvisionDnsZoneTransportException() throws Exception {
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(serverVO);
|
||||
when(dnsProviderMock.provisionZone(any(), any())).thenThrow(new DnsTransportException("unreachable", new IOException("i/o")));
|
||||
manager.provisionDnsZone(ZONE_ID);
|
||||
verify(dnsZoneDao).remove(ZONE_ID);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testDeleteDnsZoneNotFound() {
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(null);
|
||||
manager.deleteDnsZone(ZONE_ID);
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testDeleteDnsZoneServerMissing() {
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(null);
|
||||
manager.deleteDnsZone(ZONE_ID);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testUpdateDnsZoneNotFound() {
|
||||
UpdateDnsZoneCmd cmd = mock(UpdateDnsZoneCmd.class);
|
||||
when(cmd.getId()).thenReturn(ZONE_ID);
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(null);
|
||||
manager.updateDnsZone(cmd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateDnsZoneNoChange() {
|
||||
UpdateDnsZoneCmd cmd = mock(UpdateDnsZoneCmd.class);
|
||||
when(cmd.getId()).thenReturn(ZONE_ID);
|
||||
when(cmd.getDescription()).thenReturn(null);
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
DnsZone result = manager.updateDnsZone(cmd);
|
||||
assertNotNull(result);
|
||||
verify(dnsZoneDao, never()).update(anyLong(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateDnsZoneWithDescription() throws Exception {
|
||||
UpdateDnsZoneCmd cmd = mock(UpdateDnsZoneCmd.class);
|
||||
when(cmd.getId()).thenReturn(ZONE_ID);
|
||||
when(cmd.getDescription()).thenReturn("Updated description");
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(serverVO);
|
||||
doNothing().when(dnsProviderMock).updateZone(any(), any());
|
||||
when(dnsZoneDao.update(anyLong(), any())).thenReturn(true);
|
||||
DnsZone result = manager.updateDnsZone(cmd);
|
||||
assertNotNull(result);
|
||||
verify(dnsProviderMock).updateZone(serverVO, zoneVO);
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testUpdateDnsZoneServerMissing() {
|
||||
UpdateDnsZoneCmd cmd = mock(UpdateDnsZoneCmd.class);
|
||||
when(cmd.getId()).thenReturn(ZONE_ID);
|
||||
when(cmd.getDescription()).thenReturn("New description");
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(null);
|
||||
manager.updateDnsZone(cmd);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testDeleteDnsServerNotFound() {
|
||||
DeleteDnsServerCmd cmd = mock(DeleteDnsServerCmd.class);
|
||||
when(cmd.getId()).thenReturn(SERVER_ID);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(null);
|
||||
manager.deleteDnsServer(cmd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDnsServerWithCleanup() throws Exception {
|
||||
DeleteDnsServerCmd cmd = mock(DeleteDnsServerCmd.class);
|
||||
when(cmd.getId()).thenReturn(SERVER_ID);
|
||||
when(cmd.getCleanup()).thenReturn(true);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(serverVO);
|
||||
doNothing().when(accountMgr).checkAccess(any(Account.class), nullable(org.apache.cloudstack.acl.SecurityChecker.AccessType.class), eq(true), any());
|
||||
|
||||
List<DnsZoneVO> zones = Collections.singletonList(zoneVO);
|
||||
when(dnsZoneDao.findDnsZonesByServerId(SERVER_ID)).thenReturn(zones);
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
when(dnsZoneNetworkMapDao.findByZoneId(ZONE_ID)).thenReturn(null);
|
||||
when(dnsServerDao.remove(SERVER_ID)).thenReturn(true);
|
||||
when(dnsZoneDao.remove(ZONE_ID)).thenReturn(true);
|
||||
|
||||
try (MockedStatic<Transaction> transactionMock = Mockito.mockStatic(Transaction.class)) {
|
||||
transactionMock.when(() -> Transaction.execute(any(TransactionCallback.class))).thenAnswer(invocation -> {
|
||||
TransactionCallback<Boolean> callback = invocation.getArgument(0);
|
||||
return callback.doInTransaction(null);
|
||||
});
|
||||
|
||||
boolean res = manager.deleteDnsServer(cmd);
|
||||
assertTrue(res);
|
||||
verify(dnsServerDao).remove(SERVER_ID);
|
||||
verify(dnsProviderMock).deleteZone(any(), any());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDnsZoneSuccess() throws Exception {
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
when(dnsServerDao.findById(anyLong())).thenReturn(serverVO);
|
||||
doNothing().when(accountMgr).checkAccess(any(Account.class), nullable(org.apache.cloudstack.acl.SecurityChecker.AccessType.class), eq(true), any());
|
||||
when(dnsZoneNetworkMapDao.findByZoneId(ZONE_ID)).thenReturn(null);
|
||||
when(dnsZoneDao.remove(ZONE_ID)).thenReturn(true);
|
||||
|
||||
try (MockedStatic<Transaction> transactionMock = Mockito.mockStatic(Transaction.class)) {
|
||||
transactionMock.when(() -> Transaction.execute(any(TransactionCallback.class))).thenAnswer(invocation -> {
|
||||
TransactionCallback<Boolean> callback = invocation.getArgument(0);
|
||||
return callback.doInTransaction(null);
|
||||
});
|
||||
|
||||
boolean res = manager.deleteDnsZone(ZONE_ID);
|
||||
assertTrue(res);
|
||||
verify(dnsZoneDao).remove(ZONE_ID);
|
||||
verify(dnsProviderMock).deleteZone(any(), any());
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testListDnsRecordsZoneNotFound() {
|
||||
ListDnsRecordsCmd cmd = mock(ListDnsRecordsCmd.class);
|
||||
when(cmd.getDnsZoneId()).thenReturn(ZONE_ID);
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(null);
|
||||
manager.listDnsRecords(cmd);
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testListDnsRecordsServerMissing() {
|
||||
ListDnsRecordsCmd cmd = mock(ListDnsRecordsCmd.class);
|
||||
when(cmd.getDnsZoneId()).thenReturn(ZONE_ID);
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(null);
|
||||
manager.listDnsRecords(cmd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListDnsRecordsSuccess() throws Exception {
|
||||
ListDnsRecordsCmd cmd = mock(ListDnsRecordsCmd.class);
|
||||
when(cmd.getDnsZoneId()).thenReturn(ZONE_ID);
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(serverVO);
|
||||
DnsRecord record = new DnsRecord("www.example.com", DnsRecord.RecordType.A, Collections.singletonList("1.2.3.4"), 300);
|
||||
when(dnsProviderMock.listRecords(any(), any())).thenReturn(Collections.singletonList(record));
|
||||
ListResponse<DnsRecordResponse> result = manager.listDnsRecords(cmd);
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.getCount().intValue());
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testListDnsRecordsZoneNotFoundInProvider() throws Exception {
|
||||
ListDnsRecordsCmd cmd = mock(ListDnsRecordsCmd.class);
|
||||
when(cmd.getDnsZoneId()).thenReturn(ZONE_ID);
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(serverVO);
|
||||
when(dnsProviderMock.listRecords(any(), any())).thenThrow(new DnsNotFoundException("not found"));
|
||||
manager.listDnsRecords(cmd);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testDisassociateZoneNoMappingFound() {
|
||||
DisassociateDnsZoneFromNetworkCmd cmd = mock(DisassociateDnsZoneFromNetworkCmd.class);
|
||||
when(cmd.getNetworkId()).thenReturn(NETWORK_ID);
|
||||
when(dnsZoneNetworkMapDao.findByNetworkId(NETWORK_ID)).thenReturn(null);
|
||||
manager.disassociateZoneFromNetwork(cmd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisassociateZoneOrphanedMapping() {
|
||||
DisassociateDnsZoneFromNetworkCmd cmd = mock(DisassociateDnsZoneFromNetworkCmd.class);
|
||||
when(cmd.getNetworkId()).thenReturn(NETWORK_ID);
|
||||
DnsZoneNetworkMapVO mapping = mock(DnsZoneNetworkMapVO.class);
|
||||
when(mapping.getDnsZoneId()).thenReturn(ZONE_ID);
|
||||
when(mapping.getId()).thenReturn(500L);
|
||||
when(dnsZoneNetworkMapDao.findByNetworkId(NETWORK_ID)).thenReturn(mapping);
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(null); // zone missing (orphan)
|
||||
when(dnsZoneNetworkMapDao.remove(500L)).thenReturn(true);
|
||||
boolean result = manager.disassociateZoneFromNetwork(cmd);
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisassociateZoneSuccess() {
|
||||
DisassociateDnsZoneFromNetworkCmd cmd = mock(DisassociateDnsZoneFromNetworkCmd.class);
|
||||
when(cmd.getNetworkId()).thenReturn(NETWORK_ID);
|
||||
DnsZoneNetworkMapVO mapping = mock(DnsZoneNetworkMapVO.class);
|
||||
when(mapping.getDnsZoneId()).thenReturn(ZONE_ID);
|
||||
when(mapping.getId()).thenReturn(500L);
|
||||
when(dnsZoneNetworkMapDao.findByNetworkId(NETWORK_ID)).thenReturn(mapping);
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
|
||||
when(dnsZoneNetworkMapDao.remove(500L)).thenReturn(true);
|
||||
boolean result = manager.disassociateZoneFromNetwork(cmd);
|
||||
assertTrue(result);
|
||||
verify(dnsZoneNetworkMapDao).remove(500L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDnsRecordResponse() {
|
||||
DnsRecord record = new DnsRecord("www.example.com", DnsRecord.RecordType.A, Arrays.asList("1.2.3.4"), 300);
|
||||
DnsRecordResponse response = manager.createDnsRecordResponse(record);
|
||||
assertNotNull(response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDnsServerResponseFromJoinVO() {
|
||||
DnsServerJoinVO join = mock(DnsServerJoinVO.class);
|
||||
when(join.getUuid()).thenReturn("uuid-1");
|
||||
when(join.getName()).thenReturn("pdns");
|
||||
when(join.getUrl()).thenReturn("http://pdns:8081");
|
||||
when(join.getPort()).thenReturn(8081);
|
||||
when(join.getProviderType()).thenReturn(DnsProviderType.PowerDNS.toString());
|
||||
when(join.isPublicServer()).thenReturn(false);
|
||||
when(join.getNameServers()).thenReturn(Collections.emptyList());
|
||||
when(join.getPublicDomainSuffix()).thenReturn(null);
|
||||
when(join.getAccountName()).thenReturn("admin");
|
||||
when(join.getDomainUuid()).thenReturn("domain-uuid");
|
||||
when(join.getDomainName()).thenReturn("ROOT");
|
||||
when(join.getState()).thenReturn(DnsServer.State.Enabled);
|
||||
DnsServerResponse response = manager.createDnsServerResponse(join);
|
||||
assertNotNull(response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDnsZoneResponseFromJoinVO() {
|
||||
DnsZoneJoinVO join = mock(DnsZoneJoinVO.class);
|
||||
when(join.getUuid()).thenReturn("zone-uuid");
|
||||
when(join.getName()).thenReturn("example.com");
|
||||
when(join.getDnsServerUuid()).thenReturn("server-uuid");
|
||||
when(join.getAccountName()).thenReturn("admin");
|
||||
when(join.getDomainUuid()).thenReturn("domain-uuid");
|
||||
when(join.getDomainName()).thenReturn("ROOT");
|
||||
when(join.getDnsServerName()).thenReturn("pdns");
|
||||
when(join.getDnsServerAccountName()).thenReturn("admin");
|
||||
when(join.getState()).thenReturn(DnsZone.State.Active);
|
||||
when(join.getDescription()).thenReturn("Test zone");
|
||||
DnsZoneResponse response = manager.createDnsZoneResponse(join);
|
||||
assertNotNull(response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDnsServerPermissionOwner() {
|
||||
// owner has same accountId as server
|
||||
when(callerMock.getId()).thenReturn(ACCOUNT_ID);
|
||||
Mockito.doReturn(ACCOUNT_ID).when(serverVO).getAccountId();
|
||||
// Should not throw
|
||||
manager.checkDnsServerPermission(callerMock, serverVO);
|
||||
}
|
||||
|
||||
@Test(expected = PermissionDeniedException.class)
|
||||
public void testCheckDnsServerPermissionNonOwnerPrivate() {
|
||||
when(callerMock.getId()).thenReturn(ACCOUNT_ID + 1);
|
||||
Mockito.doReturn(ACCOUNT_ID).when(serverVO).getAccountId();
|
||||
Mockito.doReturn(false).when(serverVO).getPublicServer();
|
||||
manager.checkDnsServerPermission(callerMock, serverVO);
|
||||
}
|
||||
|
||||
@Test(expected = PermissionDeniedException.class)
|
||||
public void testCheckDnsServerPermissionNonOwnerPublicOutsideDomain() {
|
||||
AccountVO serverOwner = mock(AccountVO.class);
|
||||
when(callerMock.getId()).thenReturn(ACCOUNT_ID + 1);
|
||||
Mockito.doReturn(ACCOUNT_ID).when(serverVO).getAccountId();
|
||||
Mockito.doReturn(true).when(serverVO).getPublicServer();
|
||||
when(serverOwner.getDomainId()).thenReturn(20L);
|
||||
when(callerMock.getDomainId()).thenReturn(DOMAIN_ID);
|
||||
ReflectionTestUtils.setField(manager, "accountDao",
|
||||
Mockito.mock(com.cloud.user.dao.AccountDao.class));
|
||||
com.cloud.user.dao.AccountDao accountDaoMock = (com.cloud.user.dao.AccountDao) ReflectionTestUtils.getField(manager, "accountDao");
|
||||
when(accountDaoMock.findByIdIncludingRemoved(ACCOUNT_ID)).thenReturn(serverOwner);
|
||||
when(domainDao.isChildDomain(20L, DOMAIN_ID)).thenReturn(false);
|
||||
manager.checkDnsServerPermission(callerMock, serverVO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDnsZonePermissionOwner() {
|
||||
when(callerMock.getId()).thenReturn(ACCOUNT_ID);
|
||||
Mockito.doReturn(ACCOUNT_ID).when(zoneVO).getAccountId();
|
||||
// Should not throw
|
||||
manager.checkDnsZonePermission(callerMock, zoneVO);
|
||||
}
|
||||
|
||||
@Test(expected = PermissionDeniedException.class)
|
||||
public void testCheckDnsZonePermissionNonOwner() {
|
||||
when(callerMock.getId()).thenReturn(ACCOUNT_ID + 1);
|
||||
Mockito.doReturn(ACCOUNT_ID).when(zoneVO).getAccountId();
|
||||
manager.checkDnsZonePermission(callerMock, zoneVO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddDnsRecordForVMNoNetworkMapping() throws DnsProviderException {
|
||||
Network network = mock(Network.class);
|
||||
NicVO nic = mock(NicVO.class);
|
||||
VMInstanceVO vm = mock(VMInstanceVO.class);
|
||||
when(dnsZoneNetworkMapDao.findByNetworkId(anyLong())).thenReturn(null);
|
||||
when(network.getId()).thenReturn(NETWORK_ID);
|
||||
manager.addDnsRecordForVM(vm, network, nic);
|
||||
verify(dnsProviderMock, never()).addRecord(any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddDnsRecordForVMInactiveZone() {
|
||||
Network network = mock(Network.class);
|
||||
NicVO nic = mock(NicVO.class);
|
||||
VMInstanceVO vm = mock(VMInstanceVO.class);
|
||||
DnsZoneNetworkMapVO mapping = mock(DnsZoneNetworkMapVO.class);
|
||||
when(network.getId()).thenReturn(NETWORK_ID);
|
||||
when(dnsZoneNetworkMapDao.findByNetworkId(NETWORK_ID)).thenReturn(mapping);
|
||||
when(mapping.getDnsZoneId()).thenReturn(ZONE_ID);
|
||||
DnsZoneVO inactiveZone = Mockito.spy(new DnsZoneVO("ex.com", DnsZone.ZoneType.Public, SERVER_ID, ACCOUNT_ID, DOMAIN_ID, ""));
|
||||
// state defaults to Inactive
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(inactiveZone);
|
||||
manager.addDnsRecordForVM(vm, network, nic);
|
||||
verify(dnsServerDao, never()).findById(anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddDnsRecordForVMServerMissing() {
|
||||
Network network = mock(Network.class);
|
||||
NicVO nic = mock(NicVO.class);
|
||||
VMInstanceVO vm = mock(VMInstanceVO.class);
|
||||
DnsZoneNetworkMapVO mapping = mock(DnsZoneNetworkMapVO.class);
|
||||
when(network.getId()).thenReturn(NETWORK_ID);
|
||||
when(dnsZoneNetworkMapDao.findByNetworkId(NETWORK_ID)).thenReturn(mapping);
|
||||
when(mapping.getDnsZoneId()).thenReturn(ZONE_ID);
|
||||
DnsZoneVO activeZone = Mockito.spy(new DnsZoneVO("ex.com", DnsZone.ZoneType.Public, SERVER_ID, ACCOUNT_ID, DOMAIN_ID, ""));
|
||||
activeZone.setState(DnsZone.State.Active);
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(activeZone);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(null);
|
||||
when(vm.getInstanceName()).thenReturn("vm-1");
|
||||
manager.addDnsRecordForVM(vm, network, nic);
|
||||
verify(nicDetailsDao, never()).addDetail(anyLong(), anyString(), anyString(), eq(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDnsRecordForVMNoNicDetail() {
|
||||
Network network = mock(Network.class);
|
||||
NicVO nic = mock(NicVO.class);
|
||||
VMInstanceVO vm = mock(VMInstanceVO.class);
|
||||
when(nic.getId()).thenReturn(50L);
|
||||
when(vm.getInstanceName()).thenReturn("vm-1");
|
||||
when(nicDetailsDao.findDetail(50L, "nicdnsrecord")).thenReturn(null);
|
||||
manager.deleteDnsRecordForVM(vm, network, nic);
|
||||
verify(dnsZoneNetworkMapDao, never()).findByNetworkId(anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDnsRecordForVMNicDetailBlankValue() {
|
||||
Network network = mock(Network.class);
|
||||
NicVO nic = mock(NicVO.class);
|
||||
VMInstanceVO vm = mock(VMInstanceVO.class);
|
||||
NicDetailVO detail = mock(NicDetailVO.class);
|
||||
when(nic.getId()).thenReturn(50L);
|
||||
when(vm.getInstanceName()).thenReturn("vm-1");
|
||||
when(nicDetailsDao.findDetail(50L, "nicdnsrecord")).thenReturn(detail);
|
||||
when(detail.getValue()).thenReturn(" ");
|
||||
manager.deleteDnsRecordForVM(vm, network, nic);
|
||||
verify(dnsZoneNetworkMapDao, never()).findByNetworkId(anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessEventForDnsRecordAdd() throws Exception {
|
||||
Network network = mock(Network.class);
|
||||
NicVO nic = mock(NicVO.class);
|
||||
VMInstanceVO vm = mock(VMInstanceVO.class);
|
||||
|
||||
when(dnsZoneNetworkMapDao.findByNetworkId(anyLong())).thenReturn(null);
|
||||
when(network.getId()).thenReturn(NETWORK_ID);
|
||||
manager.processEventForDnsRecord(vm, network, nic, true);
|
||||
// addDnsRecordForVM was called → returns early because no mapping
|
||||
verify(dnsZoneNetworkMapDao, times(1)).findByNetworkId(NETWORK_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessEventForDnsRecordDelete() {
|
||||
Network network = mock(Network.class);
|
||||
NicVO nic = mock(NicVO.class);
|
||||
VMInstanceVO vm = mock(VMInstanceVO.class);
|
||||
|
||||
when(nic.getId()).thenReturn(50L);
|
||||
when(vm.getInstanceName()).thenReturn("vm-1");
|
||||
when(nicDetailsDao.findDetail(50L, "nicdnsrecord")).thenReturn(null);
|
||||
manager.processEventForDnsRecord(vm, network, nic, false);
|
||||
verify(nicDetailsDao, times(1)).findDetail(50L, "nicdnsrecord");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCommandsReturnsNonEmptyList() {
|
||||
List<Class<?>> commands = manager.getCommands();
|
||||
assertNotNull(commands);
|
||||
assertFalse(commands.isEmpty());
|
||||
assertTrue(commands.size() > 5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartWithNoProviders() {
|
||||
manager.setDnsProviders(Collections.emptyList());
|
||||
assertTrue(manager.start());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartWithProviders() {
|
||||
assertTrue(manager.start());
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testAssociateZoneToNetworkZoneNotFound() {
|
||||
org.apache.cloudstack.api.command.user.dns.AssociateDnsZoneToNetworkCmd cmd =
|
||||
mock(org.apache.cloudstack.api.command.user.dns.AssociateDnsZoneToNetworkCmd.class);
|
||||
when(cmd.getDnsZoneId()).thenReturn(ZONE_ID);
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(null);
|
||||
manager.associateZoneToNetwork(cmd);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testAssociateZoneToNetworkNetworkNotFound() {
|
||||
org.apache.cloudstack.api.command.user.dns.AssociateDnsZoneToNetworkCmd cmd =
|
||||
mock(org.apache.cloudstack.api.command.user.dns.AssociateDnsZoneToNetworkCmd.class);
|
||||
when(cmd.getDnsZoneId()).thenReturn(ZONE_ID);
|
||||
when(cmd.getNetworkId()).thenReturn(NETWORK_ID);
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(serverVO);
|
||||
when(networkDao.findById(NETWORK_ID)).thenReturn(null);
|
||||
manager.associateZoneToNetwork(cmd);
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testAssociateZoneToNetworkNonSharedNetwork() {
|
||||
org.apache.cloudstack.api.command.user.dns.AssociateDnsZoneToNetworkCmd cmd =
|
||||
mock(org.apache.cloudstack.api.command.user.dns.AssociateDnsZoneToNetworkCmd.class);
|
||||
when(cmd.getDnsZoneId()).thenReturn(ZONE_ID);
|
||||
when(cmd.getNetworkId()).thenReturn(NETWORK_ID);
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(serverVO);
|
||||
NetworkVO network = mock(NetworkVO.class);
|
||||
when(network.getGuestType()).thenReturn(NetworkVO.GuestType.Isolated);
|
||||
when(networkDao.findById(NETWORK_ID)).thenReturn(network);
|
||||
manager.associateZoneToNetwork(cmd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAssociateZoneToNetworkSuccess() {
|
||||
org.apache.cloudstack.api.command.user.dns.AssociateDnsZoneToNetworkCmd cmd =
|
||||
mock(org.apache.cloudstack.api.command.user.dns.AssociateDnsZoneToNetworkCmd.class);
|
||||
when(cmd.getDnsZoneId()).thenReturn(ZONE_ID);
|
||||
when(cmd.getNetworkId()).thenReturn(NETWORK_ID);
|
||||
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
Mockito.doReturn("zone-uuid").when(zoneVO).getUuid();
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(serverVO);
|
||||
NetworkVO network = mock(NetworkVO.class);
|
||||
when(network.getGuestType()).thenReturn(NetworkVO.GuestType.Shared);
|
||||
|
||||
when(networkDao.findById(NETWORK_ID)).thenReturn(network);
|
||||
DnsZoneNetworkMapVO savedMapping = mock(DnsZoneNetworkMapVO.class);
|
||||
when(dnsZoneNetworkMapDao.persist(any(DnsZoneNetworkMapVO.class))).thenReturn(savedMapping);
|
||||
DnsZoneNetworkMapResponse response = manager.associateZoneToNetwork(cmd);
|
||||
assertNotNull(response);
|
||||
verify(dnsZoneNetworkMapDao).persist(any(DnsZoneNetworkMapVO.class));
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testAssociateZoneToNetworkAlreadyAssociated() {
|
||||
org.apache.cloudstack.api.command.user.dns.AssociateDnsZoneToNetworkCmd cmd =
|
||||
mock(org.apache.cloudstack.api.command.user.dns.AssociateDnsZoneToNetworkCmd.class);
|
||||
when(cmd.getDnsZoneId()).thenReturn(ZONE_ID);
|
||||
when(cmd.getNetworkId()).thenReturn(NETWORK_ID);
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(serverVO);
|
||||
NetworkVO network = mock(NetworkVO.class);
|
||||
when(network.getGuestType()).thenReturn(NetworkVO.GuestType.Shared);
|
||||
when(network.getId()).thenReturn(NETWORK_ID);
|
||||
when(networkDao.findById(NETWORK_ID)).thenReturn(network);
|
||||
when(dnsZoneNetworkMapDao.findByNetworkId(NETWORK_ID)).thenReturn(mock(DnsZoneNetworkMapVO.class));
|
||||
manager.associateZoneToNetwork(cmd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDnsRecordSuccess() throws Exception {
|
||||
org.apache.cloudstack.api.command.user.dns.CreateDnsRecordCmd cmd = mock(org.apache.cloudstack.api.command.user.dns.CreateDnsRecordCmd.class);
|
||||
when(cmd.getName()).thenReturn("www");
|
||||
when(cmd.getDnsZoneId()).thenReturn(ZONE_ID);
|
||||
when(cmd.getType()).thenReturn(DnsRecord.RecordType.A);
|
||||
when(cmd.getContents()).thenReturn(Collections.singletonList("1.2.3.4"));
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
when(dnsServerDao.findById(anyLong())).thenReturn(serverVO);
|
||||
when(dnsProviderMock.addRecord(any(), any(), any())).thenReturn("www.example.com");
|
||||
|
||||
DnsRecordResponse res = manager.createDnsRecord(cmd);
|
||||
assertNotNull(res);
|
||||
verify(dnsProviderMock).addRecord(any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDnsRecordSuccess() throws Exception {
|
||||
org.apache.cloudstack.api.command.user.dns.DeleteDnsRecordCmd cmd = mock(org.apache.cloudstack.api.command.user.dns.DeleteDnsRecordCmd.class);
|
||||
when(cmd.getDnsZoneId()).thenReturn(ZONE_ID);
|
||||
when(cmd.getName()).thenReturn("www");
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
when(dnsServerDao.findById(anyLong())).thenReturn(serverVO);
|
||||
when(dnsProviderMock.deleteRecord(any(), any(), any())).thenReturn("www.example.com");
|
||||
|
||||
boolean res = manager.deleteDnsRecord(cmd);
|
||||
assertTrue(res);
|
||||
verify(dnsProviderMock).deleteRecord(any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDnsRecordForVMSuccess() throws Exception {
|
||||
Network network = mock(Network.class);
|
||||
NicVO nic = mock(NicVO.class);
|
||||
when(nic.getIPv4Address()).thenReturn("1.2.3.4");
|
||||
VMInstanceVO vm = mock(VMInstanceVO.class);
|
||||
NicDetailVO detail = mock(NicDetailVO.class);
|
||||
when(nic.getId()).thenReturn(50L);
|
||||
when(vm.getInstanceName()).thenReturn("vm-1");
|
||||
when(nicDetailsDao.findDetail(50L, "nicdnsrecord")).thenReturn(detail);
|
||||
when(detail.getValue()).thenReturn("vm-1.ex.com");
|
||||
|
||||
DnsZoneNetworkMapVO mapping = mock(DnsZoneNetworkMapVO.class);
|
||||
when(network.getId()).thenReturn(NETWORK_ID);
|
||||
when(dnsZoneNetworkMapDao.findByNetworkId(NETWORK_ID)).thenReturn(mapping);
|
||||
when(mapping.getDnsZoneId()).thenReturn(ZONE_ID);
|
||||
when(dnsZoneDao.findById(ZONE_ID)).thenReturn(zoneVO);
|
||||
when(dnsServerDao.findById(anyLong())).thenReturn(serverVO);
|
||||
when(dnsProviderMock.deleteRecord(any(), any(), any())).thenReturn("vm-1.ex.com");
|
||||
|
||||
manager.deleteDnsRecordForVM(vm, network, nic);
|
||||
verify(dnsProviderMock).deleteRecord(any(), any(), any());
|
||||
verify(nicDetailsDao).removeDetail(50L, "nicdnsrecord");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigure() throws Exception {
|
||||
assertTrue(manager.configure("dnsProviderManagerImpl", Collections.emptyMap()));
|
||||
verify(messageBus, times(3)).subscribe(anyString(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleVmEventAndNicEvent() throws Exception {
|
||||
VMInstanceVO vm = mock(VMInstanceVO.class);
|
||||
NicVO nic = mock(NicVO.class);
|
||||
NetworkVO network = mock(NetworkVO.class);
|
||||
when(network.getId()).thenReturn(NETWORK_ID);
|
||||
|
||||
when(vmInstanceDao.findById(10L)).thenReturn(vm);
|
||||
when(nicDao.findByIdIncludingRemoved(50L)).thenReturn(nic);
|
||||
when(nic.getNetworkId()).thenReturn(NETWORK_ID);
|
||||
when(networkDao.findById(NETWORK_ID)).thenReturn(network);
|
||||
when(network.getGuestType()).thenReturn(Network.GuestType.Shared);
|
||||
when(dnsZoneNetworkMapDao.findByNetworkId(NETWORK_ID)).thenReturn(null);
|
||||
|
||||
org.springframework.test.util.ReflectionTestUtils.invokeMethod(manager, "handleNicEvent", 50L, 10L, true);
|
||||
verify(dnsZoneNetworkMapDao, times(1)).findByNetworkId(NETWORK_ID);
|
||||
|
||||
when(vmInstanceDao.findByIdIncludingRemoved(10L)).thenReturn(vm);
|
||||
when(vm.getId()).thenReturn(10L);
|
||||
when(nicDao.listByVmIdIncludingRemoved(10L)).thenReturn(Collections.singletonList(nic));
|
||||
|
||||
org.springframework.test.util.ReflectionTestUtils.invokeMethod(manager, "handleVmEvent", 10L, true);
|
||||
verify(dnsZoneNetworkMapDao, times(2)).findByNetworkId(NETWORK_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddDnsServerSuccess() throws Exception {
|
||||
org.apache.cloudstack.api.command.user.dns.AddDnsServerCmd cmd = mock(org.apache.cloudstack.api.command.user.dns.AddDnsServerCmd.class);
|
||||
when(callerMock.getType()).thenReturn(Account.Type.ADMIN);
|
||||
when(cmd.getUrl()).thenReturn("http://newpdns:8081");
|
||||
when(cmd.getProvider()).thenReturn(DnsProviderType.PowerDNS);
|
||||
when(dnsServerDao.findByUrlAndAccount(anyString(), anyLong())).thenReturn(null);
|
||||
when(dnsProviderMock.validateAndResolveServer(any())).thenReturn("resolved-id");
|
||||
when(dnsServerDao.persist(any())).thenReturn(serverVO);
|
||||
DnsServer result = manager.addDnsServer(cmd);
|
||||
assertNotNull(result);
|
||||
verify(dnsServerDao).persist(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListDnsServers() {
|
||||
org.apache.cloudstack.api.command.user.dns.ListDnsServersCmd cmd = mock(org.apache.cloudstack.api.command.user.dns.ListDnsServersCmd.class);
|
||||
when(domainDao.getDomainParentIds(anyLong())).thenReturn(Collections.emptySet());
|
||||
List<DnsServerVO> servers = Collections.singletonList(serverVO);
|
||||
com.cloud.utils.Pair<List<DnsServerVO>, Integer> searchPair = new com.cloud.utils.Pair<>(servers, 1);
|
||||
when(dnsServerDao.searchDnsServer(any(), anyLong(), any(), any(), any(), any())).thenReturn(searchPair);
|
||||
|
||||
DnsServerJoinVO joinVO = mock(DnsServerJoinVO.class);
|
||||
when(joinVO.getProviderType()).thenReturn(DnsProviderType.PowerDNS.toString());
|
||||
when(joinVO.getState()).thenReturn(DnsServer.State.Enabled);
|
||||
when(dnsServerJoinDao.listByUuids(any())).thenReturn(Collections.singletonList(joinVO));
|
||||
|
||||
ListResponse<DnsServerResponse> res = manager.listDnsServers(cmd);
|
||||
assertEquals(1, res.getCount().intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateDnsServer() throws Exception {
|
||||
org.apache.cloudstack.api.command.user.dns.UpdateDnsServerCmd cmd = mock(org.apache.cloudstack.api.command.user.dns.UpdateDnsServerCmd.class);
|
||||
when(cmd.getId()).thenReturn(SERVER_ID);
|
||||
when(cmd.getName()).thenReturn("updated-name");
|
||||
when(dnsServerDao.findById(SERVER_ID)).thenReturn(serverVO);
|
||||
when(dnsServerDao.update(eq(SERVER_ID), any())).thenReturn(true);
|
||||
DnsServer res = manager.updateDnsServer(cmd);
|
||||
assertNotNull(res);
|
||||
verify(dnsServerDao).update(eq(SERVER_ID), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListDnsZones() {
|
||||
org.apache.cloudstack.api.command.user.dns.ListDnsZonesCmd cmd = mock(org.apache.cloudstack.api.command.user.dns.ListDnsZonesCmd.class);
|
||||
when(cmd.getId()).thenReturn(null);
|
||||
when(dnsServerDao.listDnsServerIdsByAccountId(anyLong())).thenReturn(Collections.emptyList());
|
||||
List<DnsZoneVO> zones = Collections.singletonList(zoneVO);
|
||||
com.cloud.utils.Pair<List<DnsZoneVO>, Integer> searchPair = new com.cloud.utils.Pair<>(zones, 1);
|
||||
when(dnsZoneDao.searchZones(any(), anyLong(), any(), any(), any(), any())).thenReturn(searchPair);
|
||||
|
||||
DnsZoneJoinVO joinVO = mock(DnsZoneJoinVO.class);
|
||||
when(dnsZoneJoinDao.listByUuids(any())).thenReturn(Collections.singletonList(joinVO));
|
||||
|
||||
ListResponse<DnsZoneResponse> res = manager.listDnsZones(cmd);
|
||||
assertEquals(1, res.getCount().intValue());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.dns;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class DnsProviderUtilTest {
|
||||
|
||||
@Test
|
||||
public void testNormalizeDnsRecordValueA() {
|
||||
String result = DnsProviderUtil.normalizeDnsRecordValue(" 1.2.3.4 ", DnsRecord.RecordType.A);
|
||||
assertEquals("1.2.3.4", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalizeDnsRecordValueAAAA() {
|
||||
String result = DnsProviderUtil.normalizeDnsRecordValue(" 2001:db8::1 ", DnsRecord.RecordType.AAAA);
|
||||
assertEquals("2001:db8::1", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalizeDnsRecordValueCNAME() {
|
||||
// Appends dot in the process? No, normalizeDomain trims, lowercases, removes trailing dot, and checks validity.
|
||||
String result = DnsProviderUtil.normalizeDnsRecordValue(" Host.Example.Com. ", DnsRecord.RecordType.CNAME);
|
||||
assertEquals("host.example.com", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalizeDnsRecordValueNS() {
|
||||
String result = DnsProviderUtil.normalizeDnsRecordValue("NS1.EXAMPLE.COM", DnsRecord.RecordType.NS);
|
||||
assertEquals("ns1.example.com", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalizeDnsRecordValuePTR() {
|
||||
String result = DnsProviderUtil.normalizeDnsRecordValue("ptr.valid.zone.", DnsRecord.RecordType.PTR);
|
||||
assertEquals("ptr.valid.zone", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalizeDnsRecordValueSRV() {
|
||||
String result = DnsProviderUtil.normalizeDnsRecordValue("srv.example.com", DnsRecord.RecordType.SRV);
|
||||
assertEquals("srv.example.com", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalizeDnsRecordValueMX() {
|
||||
// MX records just get trimmed and lowercased
|
||||
String result = DnsProviderUtil.normalizeDnsRecordValue(" 10 MAIL.EXAMPLE.COM ", DnsRecord.RecordType.MX);
|
||||
assertEquals("10 mail.example.com", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalizeDnsRecordValueTXT() {
|
||||
// TXT records are preserved exactly
|
||||
String result = DnsProviderUtil.normalizeDnsRecordValue(" Exact text value. ", DnsRecord.RecordType.TXT);
|
||||
assertEquals(" Exact text value. ", result);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testNormalizeDnsRecordValueEmpty() {
|
||||
DnsProviderUtil.normalizeDnsRecordValue(" ", DnsRecord.RecordType.A);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testNormalizeDnsRecordValueNull() {
|
||||
DnsProviderUtil.normalizeDnsRecordValue(null, DnsRecord.RecordType.A);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testNormalizeDnsRecordValueInvalidDomain() {
|
||||
DnsProviderUtil.normalizeDnsRecordValue("invalid!domain", DnsRecord.RecordType.CNAME);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.dns.dao;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.cloudstack.dns.DnsProviderType;
|
||||
import org.apache.cloudstack.dns.DnsServer;
|
||||
import org.apache.cloudstack.dns.vo.DnsServerVO;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DnsServerDaoImplTest {
|
||||
|
||||
DnsServerDaoImpl dao;
|
||||
DnsServerVO mockServer;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
dao = spy(new DnsServerDaoImpl());
|
||||
mockServer = new DnsServerVO("test-server", "http://pdns:8081", 8081, "localhost", DnsProviderType.PowerDNS, null, "apikey", false, null, Collections.singletonList("ns1.example.com"), 1L, 10L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindByUrlAndAccount() {
|
||||
doReturn(mockServer).when(dao).findOneBy(any(SearchCriteria.class));
|
||||
|
||||
DnsServer result = dao.findByUrlAndAccount("http://pdns:8081", 1L);
|
||||
assertNotNull(result);
|
||||
assertEquals("test-server", result.getName());
|
||||
assertEquals("http://pdns:8081", result.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListDnsServerIdsByAccountId() {
|
||||
List<Long> expectedIds = Arrays.asList(100L);
|
||||
doReturn(expectedIds).when(dao).customSearch(any(SearchCriteria.class), any());
|
||||
|
||||
List<Long> result = dao.listDnsServerIdsByAccountId(1L);
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(100L, result.get(0).longValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListDnsServerIdsByAccountIdNullAccount() {
|
||||
List<Long> expectedIds = Arrays.asList(100L, 200L);
|
||||
doReturn(expectedIds).when(dao).customSearch(any(SearchCriteria.class), any());
|
||||
|
||||
List<Long> result = dao.listDnsServerIdsByAccountId(null);
|
||||
assertNotNull(result);
|
||||
assertEquals(2, result.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchDnsServerWithAllParams() {
|
||||
List<DnsServerVO> expected = Collections.singletonList(mockServer);
|
||||
Pair<List<DnsServerVO>, Integer> expectedPair = new Pair<>(expected, 1);
|
||||
doReturn(expectedPair).when(dao).searchAndCount(any(SearchCriteria.class), any());
|
||||
|
||||
Filter filter = new Filter(DnsServerVO.class, "id", true, 0L, 10L);
|
||||
Set<Long> domainIds = new HashSet<>(Arrays.asList(10L, 20L));
|
||||
Pair<List<DnsServerVO>, Integer> result = dao.searchDnsServer(100L, 1L, domainIds, DnsProviderType.PowerDNS, "test", filter);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.first().size());
|
||||
assertEquals(1, result.second().intValue());
|
||||
assertEquals("test-server", result.first().get(0).getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchDnsServerWithNullParams() {
|
||||
List<DnsServerVO> expected = Collections.singletonList(mockServer);
|
||||
Pair<List<DnsServerVO>, Integer> expectedPair = new Pair<>(expected, 1);
|
||||
doReturn(expectedPair).when(dao).searchAndCount(any(SearchCriteria.class), any());
|
||||
|
||||
Filter filter = new Filter(DnsServerVO.class, "id", true, 0L, 10L);
|
||||
Set<Long> domainIds = new HashSet<>();
|
||||
Pair<List<DnsServerVO>, Integer> result = dao.searchDnsServer(null, null, domainIds, null, null, filter);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.first().size());
|
||||
assertEquals(1, result.second().intValue());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.dns.dao;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.dns.DnsZone;
|
||||
import org.apache.cloudstack.dns.vo.DnsZoneVO;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DnsZoneDaoImplTest {
|
||||
|
||||
DnsZoneDaoImpl dao;
|
||||
DnsZoneVO mockZone;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
dao = spy(new DnsZoneDaoImpl());
|
||||
mockZone = new DnsZoneVO("example.com", DnsZone.ZoneType.Public, 1L, 10L, 100L, "test zone");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListByAccount() {
|
||||
List<DnsZoneVO> expected = Collections.singletonList(mockZone);
|
||||
doReturn(expected).when(dao).listBy(any(SearchCriteria.class));
|
||||
|
||||
List<DnsZoneVO> result = dao.listByAccount(10L);
|
||||
assertEquals(1, result.size());
|
||||
assertEquals("example.com", result.get(0).getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindByNameServerAndType() {
|
||||
doReturn(mockZone).when(dao).findOneBy(any(SearchCriteria.class));
|
||||
|
||||
DnsZoneVO result = dao.findByNameServerAndType("example.com", 1L, DnsZone.ZoneType.Public);
|
||||
assertNotNull(result);
|
||||
assertEquals("example.com", result.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindDnsZonesByServerId() {
|
||||
List<DnsZoneVO> expected = Collections.singletonList(mockZone);
|
||||
doReturn(expected).when(dao).listBy(any(SearchCriteria.class));
|
||||
|
||||
List<DnsZoneVO> result = dao.findDnsZonesByServerId(1L);
|
||||
assertEquals(1, result.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchZonesWithAllParams() {
|
||||
List<DnsZoneVO> expected = Collections.singletonList(mockZone);
|
||||
Pair<List<DnsZoneVO>, Integer> expectedPair = new Pair<>(expected, 1);
|
||||
doReturn(expectedPair).when(dao).searchAndCount(any(SearchCriteria.class), any());
|
||||
|
||||
Filter filter = new Filter(DnsZoneVO.class, "id", true, 0L, 10L);
|
||||
List<Long> ownDnsServerIds = Arrays.asList(1L, 2L);
|
||||
Pair<List<DnsZoneVO>, Integer> result = dao.searchZones(1L, 10L, ownDnsServerIds, 1L, "example", filter);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.first().size());
|
||||
assertEquals(1, result.second().intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchZonesWithNullParams() {
|
||||
List<DnsZoneVO> expected = Collections.singletonList(mockZone);
|
||||
Pair<List<DnsZoneVO>, Integer> expectedPair = new Pair<>(expected, 1);
|
||||
doReturn(expectedPair).when(dao).searchAndCount(any(SearchCriteria.class), any());
|
||||
|
||||
Filter filter = new Filter(DnsZoneVO.class, "id", true, 0L, 10L);
|
||||
List<Long> ownDnsServerIds = new ArrayList<>();
|
||||
Pair<List<DnsZoneVO>, Integer> result = dao.searchZones(null, null, ownDnsServerIds, null, null, filter);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.first().size());
|
||||
assertEquals(1, result.second().intValue());
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue