/**
* 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.ambari.server.orm.dao;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.H2DatabaseCleaner;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.orm.GuiceJpaInitializer;
import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
import org.apache.ambari.server.orm.OrmTestHelper;
import org.apache.ambari.server.orm.entities.ClusterEntity;
import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
import org.apache.ambari.server.orm.entities.HostEntity;
import org.apache.ambari.server.orm.entities.HostVersionEntity;
import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
import org.apache.ambari.server.orm.entities.ResourceEntity;
import org.apache.ambari.server.orm.entities.ResourceTypeEntity;
import org.apache.ambari.server.orm.entities.StackEntity;
import org.apache.ambari.server.security.authorization.ResourceType;
import org.apache.ambari.server.state.RepositoryVersionState;
import org.apache.ambari.server.state.StackId;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
* {@link org.apache.ambari.server.orm.dao.HostVersionDAO} unit tests.
*/
public class HostVersionDAOTest {
private static Injector injector;
private ResourceTypeDAO resourceTypeDAO;
private ClusterDAO clusterDAO;
private StackDAO stackDAO;
private ClusterVersionDAO clusterVersionDAO;
private HostDAO hostDAO;
private HostVersionDAO hostVersionDAO;
private OrmTestHelper helper;
private final static StackId HDP_22_STACK = new StackId("HDP", "2.2.0");
private final static StackId BAD_STACK = new StackId("BADSTACK", "1.0");
private final static String repoVersion_2200 = "2.2.0.0-1";
private final static String repoVersion_2201 = "2.2.0.1-2";
private final static String repoVersion_2202 = "2.2.0.2-3";
@Before
public void before() {
injector = Guice.createInjector(new InMemoryDefaultTestModule());
H2DatabaseCleaner.resetSequences(injector);
injector.getInstance(GuiceJpaInitializer.class);
resourceTypeDAO = injector.getInstance(ResourceTypeDAO.class);
clusterDAO = injector.getInstance(ClusterDAO.class);
stackDAO = injector.getInstance(StackDAO.class);
clusterVersionDAO = injector.getInstance(ClusterVersionDAO.class);
hostDAO = injector.getInstance(HostDAO.class);
hostVersionDAO = injector.getInstance(HostVersionDAO.class);
helper = injector.getInstance(OrmTestHelper.class);
// required to populate the database with stacks
injector.getInstance(AmbariMetaInfo.class);
createDefaultData();
}
/**
* Helper function to bootstrap some basic data about clusters, cluster version, host, and host versions.
*/
private void createDefaultData() {
StackEntity stackEntity = stackDAO.find(HDP_22_STACK.getStackName(), HDP_22_STACK.getStackVersion());
Assert.assertNotNull(stackEntity);
// Create the cluster
ResourceTypeEntity resourceTypeEntity = new ResourceTypeEntity();
resourceTypeEntity.setId(ResourceType.CLUSTER.getId());
resourceTypeEntity.setName(ResourceType.CLUSTER.name());
resourceTypeEntity = resourceTypeDAO.merge(resourceTypeEntity);
ResourceEntity resourceEntity = new ResourceEntity();
resourceEntity.setResourceType(resourceTypeEntity);
ClusterEntity clusterEntity = new ClusterEntity();
clusterEntity.setClusterName("test_cluster1");
clusterEntity.setClusterInfo("test_cluster_info1");
clusterEntity.setResource(resourceEntity);
clusterEntity.setDesiredStack(stackEntity);
clusterDAO.create(clusterEntity);
RepositoryVersionEntity repoVersionEntity = helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2200);
// Create the Cluster Version and link it to the cluster
ClusterVersionEntity clusterVersionEntity = new ClusterVersionEntity(
clusterEntity, repoVersionEntity, RepositoryVersionState.CURRENT,
System.currentTimeMillis(), System.currentTimeMillis(), "admin");
List<ClusterVersionEntity> clusterVersionEntities = new ArrayList<>();
clusterVersionEntities.add(clusterVersionEntity);
clusterEntity.setClusterVersionEntities(clusterVersionEntities);
clusterVersionDAO.create(clusterVersionEntity);
clusterDAO.merge(clusterEntity);
// Create the hosts
HostEntity host1 = new HostEntity();
HostEntity host2 = new HostEntity();
HostEntity host3 = new HostEntity();
host1.setHostName("test_host1");
host2.setHostName("test_host2");
host3.setHostName("test_host3");
host1.setIpv4("192.168.0.1");
host2.setIpv4("192.168.0.2");
host3.setIpv4("192.168.0.3");
List<HostEntity> hostEntities = new ArrayList<>();
hostEntities.add(host1);
hostEntities.add(host2);
hostEntities.add(host3);
// Both sides of relation should be set when modifying in runtime
host1.setClusterEntities(Arrays.asList(clusterEntity));
host2.setClusterEntities(Arrays.asList(clusterEntity));
host3.setClusterEntities(Arrays.asList(clusterEntity));
hostDAO.create(host1);
hostDAO.create(host2);
hostDAO.create(host3);
clusterEntity.setHostEntities(hostEntities);
clusterDAO.merge(clusterEntity);
// Create the Host Versions
HostVersionEntity hostVersionEntity1 = new HostVersionEntity(host1, clusterVersionEntity.getRepositoryVersion(), RepositoryVersionState.CURRENT);
HostVersionEntity hostVersionEntity2 = new HostVersionEntity(host2, clusterVersionEntity.getRepositoryVersion(), RepositoryVersionState.INSTALLED);
HostVersionEntity hostVersionEntity3 = new HostVersionEntity(host3, clusterVersionEntity.getRepositoryVersion(), RepositoryVersionState.INSTALLED);
hostVersionDAO.create(hostVersionEntity1);
hostVersionDAO.create(hostVersionEntity2);
hostVersionDAO.create(hostVersionEntity3);
}
/**
* Helper function to bootstrap additional data on top of the default data.
*/
private void addMoreVersions() {
ClusterEntity clusterEntity = clusterDAO.findByName("test_cluster1");
// Create another Cluster Version and mark the old one as INSTALLED
if (clusterEntity.getClusterVersionEntities() != null && clusterEntity.getClusterVersionEntities().size() > 0) {
ClusterVersionEntity installedClusterVersion = clusterVersionDAO.findByClusterAndStateCurrent(clusterEntity.getClusterName());
installedClusterVersion.setState(RepositoryVersionState.INSTALLED);
clusterVersionDAO.merge(installedClusterVersion);
} else {
Assert.fail("Cluster is expected to have at least one cluster version");
}
RepositoryVersionEntity repositoryVersionEnt_2_2_0_1 = helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2201);
ClusterVersionEntity newClusterVersionEntity = new ClusterVersionEntity(clusterEntity, repositoryVersionEnt_2_2_0_1, RepositoryVersionState.CURRENT, System.currentTimeMillis(), System.currentTimeMillis(), "admin");
clusterEntity.addClusterVersionEntity(newClusterVersionEntity);
clusterVersionDAO.create(newClusterVersionEntity);
HostEntity[] hostEntities = clusterEntity.getHostEntities().toArray(new HostEntity[clusterEntity.getHostEntities().size()]);
// Must sort by host name in ascending order to ensure that state is accurately set later on.
Arrays.sort(hostEntities);
// For each of the hosts, add a host version
for (HostEntity host : hostEntities) {
HostVersionEntity hostVersionEntity = new HostVersionEntity(host, helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2201), RepositoryVersionState.INSTALLED);
hostVersionDAO.create(hostVersionEntity);
}
// For each of the hosts, add one more host version
RepositoryVersionEntity repositoryVersionEnt_2_2_0_2 = helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2202);
for (int i = 0; i < hostEntities.length; i++) {
RepositoryVersionState desiredState = null;
if (i % 3 == 0) {
desiredState = RepositoryVersionState.INSTALLED;
}
if (i % 3 == 1) {
desiredState = RepositoryVersionState.INSTALLING;
}
if (i % 3 == 2) {
desiredState = RepositoryVersionState.INSTALL_FAILED;
}
HostVersionEntity hostVersionEntity = new HostVersionEntity(hostEntities[i], repositoryVersionEnt_2_2_0_2, desiredState);
hostVersionDAO.create(hostVersionEntity);
}
}
/**
* Test the {@link HostVersionDAO#findAll()} method.
*/
@Test
public void testFindAll() {
Assert.assertEquals(3, hostVersionDAO.findAll().size());
}
/**
* Test the {@link HostVersionDAO#findByHost(String)} method.
*/
@Test
public void testFindByHost() {
Assert.assertEquals(1, hostVersionDAO.findByHost("test_host1").size());
Assert.assertEquals(1, hostVersionDAO.findByHost("test_host2").size());
Assert.assertEquals(1, hostVersionDAO.findByHost("test_host3").size());
addMoreVersions();
Assert.assertEquals(3, hostVersionDAO.findByHost("test_host1").size());
Assert.assertEquals(3, hostVersionDAO.findByHost("test_host2").size());
Assert.assertEquals(3, hostVersionDAO.findByHost("test_host3").size());
}
/**
* Test the {@link HostVersionDAO#findByClusterStackAndVersion(String, org.apache.ambari.server.state.StackId, String)} method.
*/
@Test
public void testFindByClusterStackAndVersion() {
Assert.assertEquals(3, hostVersionDAO.findByClusterStackAndVersion("test_cluster1", HDP_22_STACK, repoVersion_2200).size());
Assert.assertEquals(3, hostVersionDAO.findAll().size());
addMoreVersions();
Assert.assertEquals(3, hostVersionDAO.findByClusterStackAndVersion("test_cluster1", HDP_22_STACK, repoVersion_2201).size());
Assert.assertEquals(3, hostVersionDAO.findByClusterStackAndVersion("test_cluster1", HDP_22_STACK, repoVersion_2202).size());
Assert.assertEquals(9, hostVersionDAO.findAll().size());
}
/**
* Test the {@link HostVersionDAO#findByClusterAndHost(String, String)} method.
*/
@Test
public void testFindByClusterAndHost() {
Assert.assertEquals(1, hostVersionDAO.findByClusterAndHost("test_cluster1", "test_host1").size());
Assert.assertEquals(1, hostVersionDAO.findByClusterAndHost("test_cluster1", "test_host2").size());
Assert.assertEquals(1, hostVersionDAO.findByClusterAndHost("test_cluster1", "test_host3").size());
addMoreVersions();
Assert.assertEquals(3, hostVersionDAO.findByClusterAndHost("test_cluster1", "test_host1").size());
Assert.assertEquals(3, hostVersionDAO.findByClusterAndHost("test_cluster1", "test_host2").size());
Assert.assertEquals(3, hostVersionDAO.findByClusterAndHost("test_cluster1", "test_host3").size());
}
/**
* Test the {@link HostVersionDAO#findByClusterHostAndState(String, String, org.apache.ambari.server.state.RepositoryVersionState)} method.
*/
@Test
public void testFindByClusterHostAndState() {
Assert.assertEquals(1, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host1", RepositoryVersionState.CURRENT).size());
Assert.assertEquals(0, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host1", RepositoryVersionState.INSTALLED).size());
Assert.assertEquals(0, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host2", RepositoryVersionState.INSTALLING).size());
Assert.assertEquals(0, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host3", RepositoryVersionState.INSTALL_FAILED).size());
addMoreVersions();
Assert.assertEquals(2, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host1", RepositoryVersionState.INSTALLED).size());
Assert.assertEquals(2, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host2", RepositoryVersionState.INSTALLED).size());
Assert.assertEquals(2, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host3", RepositoryVersionState.INSTALLED).size());
Assert.assertEquals(1, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host1", RepositoryVersionState.CURRENT).size());
Assert.assertEquals(1, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host2", RepositoryVersionState.INSTALLING).size());
Assert.assertEquals(1, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host3", RepositoryVersionState.INSTALL_FAILED).size());
}
/**
* Test the {@link HostVersionDAO#findByClusterStackVersionAndHost(String, StackId, String, String)} method.
*/
@Test
public void testFindByClusterStackVersionAndHost() {
HostEntity host1 = hostDAO.findByName("test_host1");
HostEntity host2 = hostDAO.findByName("test_host2");
HostEntity host3 = hostDAO.findByName("test_host3");
HostVersionEntity hostVersionEntity1 = new HostVersionEntity(host1,
helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2200), RepositoryVersionState.CURRENT);
hostVersionEntity1.setId(1L);
HostVersionEntity hostVersionEntity2 = new HostVersionEntity(host2,
helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2200), RepositoryVersionState.INSTALLED);
hostVersionEntity2.setId(2L);
HostVersionEntity hostVersionEntity3 = new HostVersionEntity(host3,
helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2200), RepositoryVersionState.INSTALLED);
hostVersionEntity3.setId(3L);
Assert.assertEquals(hostVersionEntity1, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, repoVersion_2200, "test_host1"));
Assert.assertEquals(hostVersionEntity2, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, repoVersion_2200, "test_host2"));
Assert.assertEquals(hostVersionEntity3, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, repoVersion_2200, "test_host3"));
// Test non-existent objects
Assert.assertEquals(null, hostVersionDAO.findByClusterStackVersionAndHost("non_existent_cluster", HDP_22_STACK, repoVersion_2200, "test_host3"));
Assert.assertEquals(null, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", BAD_STACK, repoVersion_2200, "test_host3"));
Assert.assertEquals(null, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, "non_existent_version", "test_host3"));
Assert.assertEquals(null, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, "non_existent_version", "non_existent_host"));
addMoreVersions();
// Expected
HostVersionEntity hostVersionEntity1LastExpected = new HostVersionEntity(host1,
helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2202), RepositoryVersionState.INSTALLED);
HostVersionEntity hostVersionEntity2LastExpected = new HostVersionEntity(host2,
helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2202), RepositoryVersionState.INSTALLING);
HostVersionEntity hostVersionEntity3LastExpected = new HostVersionEntity(host3,
helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2202), RepositoryVersionState.INSTALL_FAILED);
// Actual
HostVersionEntity hostVersionEntity1LastActual = hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, repoVersion_2202, "test_host1");
HostVersionEntity hostVersionEntity2LastActual = hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, repoVersion_2202, "test_host2");
HostVersionEntity hostVersionEntity3LastActual = hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, repoVersion_2202, "test_host3");
// Trying to Mock the actual objects to override the getId() method will not work because the class that mockito creates
// is still a Mockito wrapper. Instead, take advantage of an overloaded constructor that ignores the Id.
Assert.assertEquals(hostVersionEntity1LastExpected, new HostVersionEntity(hostVersionEntity1LastActual));
Assert.assertEquals(hostVersionEntity2LastExpected, new HostVersionEntity(hostVersionEntity2LastActual));
Assert.assertEquals(hostVersionEntity3LastExpected, new HostVersionEntity(hostVersionEntity3LastActual));
}
@Test
public void testDuplicates() throws Exception {
HostEntity host1 = hostDAO.findByName("test_host1");
RepositoryVersionEntity repoVersion = helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2200);
HostVersionEntity hostVersionEntity1 = new HostVersionEntity(host1, repoVersion, RepositoryVersionState.CURRENT);
try {
hostVersionDAO.create(hostVersionEntity1);
Assert.fail("Each host can have a relationship to a repo version, but cannot have more than one for the same repo");
} catch (Exception e) {
// expected
}
}
@After
public void after() throws AmbariException, SQLException {
H2DatabaseCleaner.clearDatabaseAndStopPersistenceService(injector);
injector = null;
}
}