/***************************************************************************
* Copyright (c) 2014 VMware, Inc. All Rights Reserved.
* Licensed 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 com.vmware.bdd.plugin.ambari.service;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.vmware.bdd.exception.SoftwareManagerCollectorException;
import com.vmware.bdd.plugin.ambari.api.exception.AmbariApiException;
import com.vmware.bdd.plugin.ambari.api.manager.ApiManager;
import com.vmware.bdd.plugin.ambari.api.model.cluster.ApiRequest;
import com.vmware.bdd.plugin.ambari.api.model.cluster.ApiRequestInfo;
import com.vmware.bdd.plugin.ambari.exception.AmException;
import com.vmware.bdd.plugin.ambari.model.AmClusterDef;
import com.vmware.bdd.plugin.ambari.service.am.FakeApiManager;
import com.vmware.bdd.software.mgmt.plugin.exception.SoftwareManagementPluginException;
import mockit.Mock;
import mockit.MockClass;
import mockit.Mockit;
import org.mockito.Mockito;
import org.testng.Assert;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.vmware.bdd.plugin.ambari.api.AmbariManagerClientbuilder;
import com.vmware.bdd.plugin.ambari.api.ApiRootResource;
import com.vmware.bdd.plugin.ambari.api.v1.RootResourceV1;
import com.vmware.bdd.plugin.ambari.service.am.FakeRootResourceV1;
import com.vmware.bdd.plugin.ambari.utils.Constants;
import com.vmware.bdd.plugin.ambari.utils.SerialUtils;
import com.vmware.bdd.software.mgmt.plugin.intf.PreStartServices;
import com.vmware.bdd.software.mgmt.plugin.intf.SoftwareManager.HealthStatus;
import com.vmware.bdd.software.mgmt.plugin.model.ClusterBlueprint;
import com.vmware.bdd.software.mgmt.plugin.model.HadoopStack;
import com.vmware.bdd.software.mgmt.plugin.monitor.ClusterReport;
import com.vmware.bdd.software.mgmt.plugin.monitor.ClusterReportQueue;
import com.vmware.bdd.software.mgmt.plugin.monitor.ServiceStatus;
import com.vmware.bdd.software.mgmt.plugin.utils.ReflectionUtils;
import com.vmware.bdd.utils.CommonUtil;
public class TestAmbariImpl {
@MockClass(realClass = ReflectionUtils.class)
public static class MockReflectionUtils {
@Mock
public static PreStartServices getPreStartServicesHook() {
return new PreStartServices() {
@Override
public void preStartServices(String clusterName,
int maxWaitingSeconds) throws SoftwareManagementPluginException {
}
};
}
}
private AmbariImpl provider;
private ClusterBlueprint blueprint;
private ClusterReportQueue reportQueue;
@BeforeTest(groups = { "TestAmbariImpl" }, dependsOnGroups = { "TestClusterDef" })
public void setup() throws IOException {
ApiRootResource apiRootResource = Mockito.mock(ApiRootResource.class);
RootResourceV1 rootResourceV1 = new FakeRootResourceV1();
Mockito.when(apiRootResource.getRootV1()).thenReturn(rootResourceV1);
AmbariManagerClientbuilder clientbuilder = Mockito.mock(AmbariManagerClientbuilder.class);
Mockito.when(clientbuilder.build()).thenReturn(apiRootResource);
AmClusterValidator validator = Mockito.mock(AmClusterValidator.class);
Mockito.when(validator.validateBlueprint(blueprint)).thenReturn(true);
//Mock static utility using Mockit.
Mockit.setUpMock(MockReflectionUtils.class);
provider = new AmbariImpl(clientbuilder, "RSA_CERT");
blueprint = SerialUtils.getObjectByJsonString(ClusterBlueprint.class,
CommonUtil.readJsonFile("simple_blueprint.json"));
reportQueue = new ClusterReportQueue();
}
@AfterTest
public void tearDown() {
//clean mock static utility using Mockit.
Mockit.tearDownMocks(ReflectionUtils.class);
}
@Test(groups = { "TestAmbariImpl" })
public void testGetName() {
Assert.assertEquals(provider.getName(), Constants.AMBARI_PLUGIN_NAME);
}
@Test(groups = { "TestAmbariImpl" })
public void testGetDescription() {
// TODO
}
@Test(groups = { "TestAmbariImpl" })
public void testGetType() {
Assert.assertEquals(provider.getType(), Constants.AMBARI_PLUGIN_NAME);
}
@Test(groups = { "TestAmbariImpl" })
public void testGetSupportedStacks() {
List<HadoopStack> supportedStacks = provider.getSupportedStacks();
for (HadoopStack supportedStack : supportedStacks) {
if (supportedStack.getFullVersion().equals(blueprint.getHadoopStack().getFullVersion())) {
Assert.assertEquals(supportedStack.getDistro(), blueprint.getHadoopStack().getDistro());
Assert.assertEquals(supportedStack.getVendor(), blueprint.getHadoopStack().getVendor());
}
}
}
@Test(groups = { "TestAmbariImpl" })
public void testEcho() {
Assert.assertTrue(provider.echo());
}
@Test(groups = { "TestAmbariImpl" })
public void testGetStatus() {
Assert.assertTrue(provider.getStatus().equals(HealthStatus.Connected));
}
@Test(groups = { "TestAmbariImpl" })
public void testGetSupportedConfigs() {
System.out.println("Supported configurations: " + provider.getSupportedConfigs(blueprint.getHadoopStack()));
Assert.assertNotNull(provider.getSupportedConfigs(blueprint.getHadoopStack()));
}
@Test(groups = { "TestAmbariImpl" })
public void testCreateCluster() {
Assert.assertTrue(provider.createCluster(blueprint, reportQueue));
}
@Test(groups = { "TestAmbariImpl" })
public void testExportBlueprint() {
// TODO
}
@Test(groups = { "TestAmbariImpl" }, dependsOnMethods = { "testCreateCluster" })
public void testStatusQuery() {
ClusterReport report = provider.queryClusterStatus(blueprint);
Assert.assertTrue(report.getStatus().equals(ServiceStatus.STARTED), "Should get started cluster status");
}
@Test(groups = { "TestAmbariImpl" })
public void testStopNotProvisioinedCluster() {
Assert.assertTrue(provider.onStopCluster(blueprint, reportQueue));
}
private AmbariManagerClientbuilder makeClientBuilder() {
ApiRootResource apiRootResource = Mockito.mock(ApiRootResource.class);
RootResourceV1 rootResourceV1 = new FakeRootResourceV1();
Mockito.when(apiRootResource.getRootV1()).thenReturn(rootResourceV1);
AmbariManagerClientbuilder clientbuilder = Mockito.mock(AmbariManagerClientbuilder.class);
Mockito.when(clientbuilder.build()).thenReturn(apiRootResource);
return clientbuilder;
}
@Test(groups = { "TestAmbariImpl" })
public void testStopClusterNotProvisionedByBDE() {
AmbariImpl ambari = Mockito.mock(AmbariImpl.class);
Mockito.when(ambari.isProvisioned(blueprint.getName())).thenReturn(true);
Mockito.when(ambari.onStopCluster(blueprint, reportQueue)).thenCallRealMethod();
try {
ambari.onStopCluster(blueprint, reportQueue);
} catch (SoftwareManagementPluginException e) {
Assert.assertNotNull(e.getCause());
String expectedErrMsg = "App_Manager (" + Constants.AMBARI_PLUGIN_NAME + ") fails to stop the cluster " +
blueprint.getName() + ": Cannot stop a cluster that is not provisioned by Big Data Extension.";
Assert.assertEquals(e.getCause().getMessage(), expectedErrMsg);
}
}
@Test(groups = { "TestAmbariImpl" })
public void testStopAlreadyStoppedCluster() {
AmbariImpl spy = Mockito.spy(provider);
AmbariManagerClientbuilder clientbuilder = makeClientBuilder();
ApiManager apiManager = new FakeApiManager(clientbuilder);
Mockito.when(spy.isProvisioned(blueprint.getName())).thenReturn(true);
Mockito.doReturn(true).when(spy).isClusterProvisionedByBDE(Mockito.<AmClusterDef>any());
ApiManager backup = spy.getApiManager();
spy.setApiManager(apiManager);
Assert.assertTrue(spy.onStopCluster(blueprint, reportQueue));
spy.setApiManager(backup);
}
@Test(groups = { "TestAmbariImpl" })
public void testStopStartedCluster() {
AmbariImpl spy = Mockito.spy(provider);
AmbariManagerClientbuilder clientbuilder = makeClientBuilder();
ApiManager apiManager = new FakeApiManager(clientbuilder) {
@Override
public ApiRequest stopAllServicesInCluster(String clusterName) throws AmbariApiException {
ApiRequest apiRequest = new ApiRequest();
apiRequest.setApiRequestInfo(new ApiRequestInfo());
return apiRequest;
}
};
Mockito.when(spy.isProvisioned(blueprint.getName())).thenReturn(true);
Mockito.doReturn(true).when(spy).isClusterProvisionedByBDE(Mockito.<AmClusterDef>any());
try {
Mockito.when(spy.doSoftwareOperation(Mockito.anyString(), Mockito.<ApiRequest>any(),
Mockito.<ClusterReport>any(), Mockito.<ClusterReportQueue>any())).thenReturn(true);
} catch (Exception e) {
}
ApiManager backup = spy.getApiManager();
spy.setApiManager(apiManager);
Assert.assertTrue(spy.onStopCluster(blueprint, reportQueue));
spy.setApiManager(backup);
}
@Test(groups = { "TestAmbariImpl" })
public void testForceDeleteClusterWithNoEcho() {
AmbariImpl spy = Mockito.spy(provider);
Mockito.when(spy.echo()).thenReturn(false);
Assert.assertTrue(spy.onDeleteCluster(blueprint, reportQueue));
}
@Test(groups = { "TestAmbariImpl" })
public void testDeleteUnprovisionedCluster() {
Assert.assertTrue(provider.onDeleteCluster(blueprint, reportQueue));
}
@Test(groups = { "TestAmbariImpl" })
public void testDeleteClusterNotProvisionedByBDE() {
AmbariImpl spy = Mockito.spy(provider);
Mockito.when(spy.echo()).thenReturn(true);
Mockito.when(spy.isProvisioned(Mockito.anyString())).thenReturn(true);
Mockito.doReturn(false).when(spy).isClusterProvisionedByBDE(Mockito.<AmClusterDef>any());
Assert.assertTrue(spy.onDeleteCluster(blueprint, reportQueue));
}
@Test(groups = { "TestAmbariImpl" })
public void testForceDeleteClusterWhenStopFailed() {
AmbariImpl spy = Mockito.spy(provider);
Mockito.when(spy.echo()).thenReturn(true);
Mockito.when(spy.isProvisioned(Mockito.anyString())).thenReturn(true);
Mockito.doReturn(true).when(spy).isClusterProvisionedByBDE(Mockito.<AmClusterDef>any());
Mockito.doReturn(false).when(spy).onStopCluster(Mockito.<ClusterBlueprint>any(), Mockito.<ClusterReportQueue>any());
ApiManager apiManager = new FakeApiManager(makeClientBuilder());
ApiManager backup = spy.getApiManager();
spy.setApiManager(apiManager);
Assert.assertTrue(spy.onDeleteCluster(blueprint, reportQueue));
spy.setApiManager(backup);
}
@Test
public void testForceDeleteClusterWhenStopSucceed() {
AmbariImpl spy = Mockito.spy(provider);
Mockito.when(spy.echo()).thenReturn(true);
Mockito.when(spy.isProvisioned(Mockito.anyString())).thenReturn(true);
Mockito.doReturn(true).when(spy).isClusterProvisionedByBDE(Mockito.<AmClusterDef>any());
Mockito.doReturn(true).when(spy).onStopCluster(Mockito.<ClusterBlueprint>any(), Mockito.<ClusterReportQueue>any());
ApiManager apiManager = new FakeApiManager(makeClientBuilder());
ApiManager backup = spy.getApiManager();
spy.setApiManager(apiManager);
Assert.assertTrue(spy.onDeleteCluster(blueprint, reportQueue));
spy.setApiManager(backup);
}
@Test(groups = { "TestAmbariImpl" })
public void testStartUnprovisionedCluster() {
try {
provider.startCluster(blueprint, reportQueue);
} catch (AmException e) {
String expectedErrMsg = "The Cluster (" + blueprint.getName() + ") has not been provisioned.";
Assert.assertEquals(e.getMessage(), expectedErrMsg);
}
}
@Test(groups = { "TestAmbariImpl" })
public void testStartClusterNotProvisionedByBDE() {
AmbariImpl ambari = Mockito.mock(AmbariImpl.class);
Mockito.when(ambari.isProvisioned(blueprint.getName())).thenReturn(true);
Mockito.when(ambari.startCluster(blueprint, reportQueue)).thenCallRealMethod();
try {
ambari.startCluster(blueprint, reportQueue);
} catch (SoftwareManagementPluginException e) {
String expectedErrMsg = "Can not start a cluster (" + blueprint.getName() + ") that is not provisioned by Big Data Extension.";
Assert.assertEquals(e.getMessage(), expectedErrMsg);
}
}
@Test(groups = { "TestAmbariImpl" })
public void testStartAlreadyStartedCluster() {
AmbariImpl spy = Mockito.spy(provider);
AmbariManagerClientbuilder clientbuilder = makeClientBuilder();
ApiManager apiManager = new FakeApiManager(clientbuilder);
Mockito.when(spy.isProvisioned(blueprint.getName())).thenReturn(true);
provider.isProvisioned(blueprint.getName());
Mockito.doReturn(true).when(spy).isClusterProvisionedByBDE(Mockito.<AmClusterDef>any());
ApiManager backup = spy.getApiManager();
spy.setApiManager(apiManager);
Assert.assertTrue(spy.startCluster(blueprint, reportQueue));
spy.setApiManager(backup);
}
@Test(groups = { "TestAmbariImpl" })
public void testStartClusterFailed() {
AmbariImpl spy = Mockito.spy(provider);
AmbariManagerClientbuilder clientbuilder = makeClientBuilder();
ApiManager apiManager = new FakeApiManager(clientbuilder) {
@Override
public ApiRequest startAllServicesInCluster(String clusterName) throws AmbariApiException {
throw AmbariApiException.RESPONSE_EXCEPTION(400, "Faked exception");
}
};
Mockito.when(spy.isProvisioned(blueprint.getName())).thenReturn(true);
Mockito.doReturn(true).when(spy).isClusterProvisionedByBDE(Mockito.<AmClusterDef>any());
Mockito.doReturn(1).when(spy).getRequestMaxRetryTimes();
ApiManager backup = spy.getApiManager();
spy.setApiManager(apiManager);
try {
spy.startCluster(blueprint, reportQueue);
} catch (SoftwareManagementPluginException e) {
Assert.assertEquals(e.getCause().getMessage(), "Ambari server error: Faked exception.");
}
spy.setApiManager(backup);
}
@Test(groups = { "TestAmbariImpl" })
public void testStartStoppedCluster() {
AmbariImpl spy = Mockito.spy(provider);
AmbariManagerClientbuilder clientbuilder = makeClientBuilder();
ApiManager apiManager = new FakeApiManager(clientbuilder) {
@Override
public ApiRequest startAllServicesInCluster(String clusterName) throws AmbariApiException {
ApiRequest apiRequest = new ApiRequest();
apiRequest.setApiRequestInfo(new ApiRequestInfo());
return apiRequest;
}
};
try {
Mockito.when(spy.doSoftwareOperation(Mockito.anyString(), Mockito.<ApiRequest>any(),
Mockito.<ClusterReport>any(), Mockito.<ClusterReportQueue>any())).thenReturn(true);
} catch (Exception e) {
}
Mockito.when(spy.isProvisioned(blueprint.getName())).thenReturn(true);
Mockito.doReturn(true).when(spy).isClusterProvisionedByBDE(Mockito.<AmClusterDef>any());
Mockito.doReturn(1).when(spy).getRequestMaxRetryTimes();
ApiManager backup = spy.getApiManager();
spy.setApiManager(apiManager);
Assert.assertTrue(spy.startCluster(blueprint, reportQueue));
spy.setApiManager(backup);
}
@Test(groups = { "TestAmbariImpl" })
public void testDoSoftwareOperation() {
ClusterReport clusterReport = new ClusterReport(blueprint);
AmbariImpl spy = Mockito.spy(provider);
ApiManager apiManager = new FakeApiManager(makeClientBuilder());
ApiManager backup = spy.getApiManager();
spy.setApiManager(apiManager);
ApiRequest request = new ApiRequest();
ApiRequestInfo requestInfo = new ApiRequestInfo();
request.setApiRequestInfo(requestInfo);
try {
spy.doSoftwareOperation(blueprint.getName(), request, clusterReport, reportQueue);
} catch (Exception e) {
e.printStackTrace();
Assert.assertTrue(e.getMessage().contains("Failed to execute request: "));
}
spy.setApiManager(backup);
}
private AmbariImpl testValidateServerVersionHelper(String version) {
AmbariImpl ambari = Mockito.mock(AmbariImpl.class);
Mockito.when(ambari.getVersion()).thenReturn(version);
Mockito.when(ambari.validateServerVersion()).thenCallRealMethod();
Mockito.when(ambari.getType()).thenCallRealMethod();
return ambari;
}
@Test(groups = { "TestAmbariImpl" })
public void testOnDeleteNodes() {
List<String> nodesToDelete = new ArrayList<>();
nodesToDelete.add(blueprint.getNodeGroups().get(0).getNodes().get(0).getHostname());
Assert.assertTrue(provider.onDeleteNodes(blueprint, nodesToDelete));
}
@Test(groups = { "TestAmbariImpl" })
public void testValidateServerVersionFailed() {
String invalidVersion = "1.5.0";
AmbariImpl ambari = testValidateServerVersionHelper(invalidVersion);
boolean exceptionExist = false;
try {
ambari.validateServerVersion();
} catch (SoftwareManagerCollectorException e) {
exceptionExist = true;
String errMsg = "The min supported version of software manager type " + ambari.getType() + " is " + ambari.MIN_SUPPORTED_VERSION + " but got " + ambari.getVersion() + ".";
Assert.assertEquals(e.getMessage(), errMsg);
}
Assert.assertTrue(exceptionExist);
}
@Test(groups = { "TestAmbariImpl" })
public void testValidateServerVersionSucceed() {
String validVersion = "1.6.0";
AmbariImpl ambari = testValidateServerVersionHelper(validVersion);
boolean exceptionExist = false;
try {
ambari.validateServerVersion();
} catch (SoftwareManagerCollectorException e) {
exceptionExist = true;
String errMsg = "The min supported version of software manager type " + ambari.getType() + " is " + ambari.MIN_SUPPORTED_VERSION + " but got " + ambari.getVersion() + ".";
Assert.assertEquals(e.getMessage(), errMsg);
}
Assert.assertTrue(!exceptionExist);
}
@Test(groups = { "TestAmbariImpl" }, dependsOnMethods = { "testStatusQuery" })
public void testClusterScaleOut() {
ClusterReportQueue queue = new ClusterReportQueue();
List<String> addedNodeNames = new ArrayList<String>();
addedNodeNames.add("cluster01-backup-0");
addedNodeNames.add("cluster01-worker-0");
Assert.assertTrue(provider.scaleOutCluster(blueprint, addedNodeNames, queue));
}
}