/**
* 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.topology;
import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.powermock.api.easymock.PowerMock.createStrictMock;
import static org.powermock.api.easymock.PowerMock.replay;
import static org.powermock.api.easymock.PowerMock.reset;
import static org.powermock.api.easymock.PowerMock.verify;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.ambari.server.ObjectNotFoundException;
import org.apache.ambari.server.controller.internal.BlueprintResourceProvider;
import org.apache.ambari.server.controller.internal.BlueprintResourceProviderTest;
import org.apache.ambari.server.controller.internal.Stack;
import org.apache.ambari.server.orm.dao.BlueprintDAO;
import org.apache.ambari.server.orm.entities.BlueprintConfigEntity;
import org.apache.ambari.server.orm.entities.BlueprintEntity;
import org.apache.ambari.server.stack.NoSuchStackException;
import org.easymock.EasyMockSupport;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* BlueprintFactory unit tests.
*/
@SuppressWarnings("unchecked")
public class BlueprintFactoryTest {
private static final String BLUEPRINT_NAME = "test-blueprint";
BlueprintFactory factory = new BlueprintFactory();
Stack stack = createNiceMock(Stack.class);
BlueprintFactory testFactory = new TestBlueprintFactory(stack);
BlueprintDAO dao = createStrictMock(BlueprintDAO.class);
BlueprintEntity entity = createStrictMock(BlueprintEntity.class);
BlueprintConfigEntity configEntity = createStrictMock(BlueprintConfigEntity.class);
@Before
public void init() throws Exception {
setPrivateField(factory, "blueprintDAO", dao);
Map<String, Collection<String>> componentMap = new HashMap<>();
Collection<String> components1 = new HashSet<>();
componentMap.put("test-service1", components1);
components1.add("component1");
Collection<String> components2 = new HashSet<>();
componentMap.put("test-service2", components2);
components2.add("component2");
expect(stack.getComponents()).andReturn(componentMap).anyTimes();
expect(stack.isMasterComponent("component1")).andReturn(true).anyTimes();
expect(stack.isMasterComponent("component2")).andReturn(false).anyTimes();
expect(stack.getServiceForComponent("component1")).andReturn("test-service1").anyTimes();
expect(stack.getServiceForComponent("component2")).andReturn("test-service2").anyTimes();
}
@After
public void tearDown() {
reset(stack, dao, entity, configEntity);
}
//todo: implement
// @Test
// public void testGetBlueprint() throws Exception {
//
// Collection<BlueprintConfigEntity> configs = new ArrayList<BlueprintConfigEntity>();
// configs.add(configEntity);
//
// expect(dao.findByName(BLUEPRINT_NAME)).andReturn(entity).once();
// expect(entity.getBlueprintName()).andReturn(BLUEPRINT_NAME).atLeastOnce();
// expect(entity.getConfigurations()).andReturn(configs).atLeastOnce();
//
// replay(dao, entity);
//
// Blueprint blueprint = factory.getBlueprint(BLUEPRINT_NAME);
//
//
// }
@Test
public void testGetBlueprint_NotFound() throws Exception {
expect(dao.findByName(BLUEPRINT_NAME)).andReturn(null).once();
replay(dao, entity, configEntity);
assertNull(factory.getBlueprint(BLUEPRINT_NAME));
}
@Test
public void testCreateBlueprint() throws Exception {
Map<String, Object> props = BlueprintResourceProviderTest.getBlueprintTestProperties().iterator().next();
replay(stack, dao, entity, configEntity);
Blueprint blueprint = testFactory.createBlueprint(props, null);
assertEquals(BLUEPRINT_NAME, blueprint.getName());
assertSame(stack, blueprint.getStack());
assertEquals(2, blueprint.getHostGroups().size());
Map<String, HostGroup> hostGroups = blueprint.getHostGroups();
HostGroup group1 = hostGroups.get("group1");
assertEquals("group1", group1.getName());
assertEquals("1", group1.getCardinality());
Collection<String> components = group1.getComponentNames();
assertEquals(2, components.size());
assertTrue(components.contains("component1"));
assertTrue(components.contains("component2"));
Collection<String> services = group1.getServices();
assertEquals(2, services.size());
assertTrue(services.contains("test-service1"));
assertTrue(services.contains("test-service2"));
assertTrue(group1.containsMasterComponent());
//todo: add configurations/attributes to properties
Configuration configuration = group1.getConfiguration();
assertTrue(configuration.getProperties().isEmpty());
assertTrue(configuration.getAttributes().isEmpty());
HostGroup group2 = hostGroups.get("group2");
assertEquals("group2", group2.getName());
assertEquals("2", group2.getCardinality());
components = group2.getComponentNames();
assertEquals(1, components.size());
assertTrue(components.contains("component1"));
services = group2.getServices();
assertEquals(1, services.size());
assertTrue(services.contains("test-service1"));
assertTrue(group2.containsMasterComponent());
//todo: add configurations/attributes to properties
//todo: test both v1 and v2 config syntax
configuration = group2.getConfiguration();
assertTrue(configuration.getProperties().isEmpty());
assertTrue(configuration.getAttributes().isEmpty());
verify(dao, entity, configEntity);
}
@Test(expected=NoSuchStackException.class)
public void testCreateInvalidStack() throws Exception {
EasyMockSupport mockSupport = new EasyMockSupport();
BlueprintFactory.StackFactory mockStackFactory =
mockSupport.createMock(BlueprintFactory.StackFactory.class);
// setup mock to throw exception, to simulate invalid stack request
expect(mockStackFactory.createStack("null", "null", null)).andThrow(new ObjectNotFoundException("Invalid Stack"));
mockSupport.replayAll();
BlueprintFactory factoryUnderTest =
new BlueprintFactory(mockStackFactory);
factoryUnderTest.createStack(new HashMap<String, Object>());
mockSupport.verifyAll();
}
@Test(expected=IllegalArgumentException.class)
public void testCreate_NoBlueprintName() throws Exception {
Map<String, Object> props = BlueprintResourceProviderTest.getBlueprintTestProperties().iterator().next();
props.remove(BlueprintResourceProvider.BLUEPRINT_NAME_PROPERTY_ID);
replay(stack, dao, entity, configEntity);
testFactory.createBlueprint(props, null);
}
@Test(expected=IllegalArgumentException.class)
public void testCreate_NoHostGroups() throws Exception {
Map<String, Object> props = BlueprintResourceProviderTest.getBlueprintTestProperties().iterator().next();
// remove all host groups
((Set<Map<String, Object>>) props.get(BlueprintResourceProvider.HOST_GROUP_PROPERTY_ID)).clear();
replay(stack, dao, entity, configEntity);
testFactory.createBlueprint(props, null);
}
@Test(expected=IllegalArgumentException.class)
public void testCreate_MissingHostGroupName() throws Exception {
Map<String, Object> props = BlueprintResourceProviderTest.getBlueprintTestProperties().iterator().next();
// remove the name property for one of the host groups
((Set<Map<String, Object>>) props.get(BlueprintResourceProvider.HOST_GROUP_PROPERTY_ID)).iterator().next().remove("name");
replay(stack, dao, entity, configEntity);
testFactory.createBlueprint(props, null);
}
@Test(expected=IllegalArgumentException.class)
public void testCreate_HostGroupWithNoComponents() throws Exception {
Map<String, Object> props = BlueprintResourceProviderTest.getBlueprintTestProperties().iterator().next();
// remove the components for one of the host groups
((Set<Map<String, Object>>) props.get(BlueprintResourceProvider.HOST_GROUP_PROPERTY_ID)).
iterator().next().remove(BlueprintResourceProvider.COMPONENT_PROPERTY_ID);
replay(stack, dao, entity, configEntity);
testFactory.createBlueprint(props, null);
}
@Test(expected=IllegalArgumentException.class)
public void testCreate_HostGroupWithInvalidComponent() throws Exception {
Map<String, Object> props = BlueprintResourceProviderTest.getBlueprintTestProperties().iterator().next();
// change a component name to an invalid name
((Set<Map<String, Object>>) ((Set<Map<String, Object>>) props.get(BlueprintResourceProvider.HOST_GROUP_PROPERTY_ID)).
iterator().next().get(BlueprintResourceProvider.COMPONENT_PROPERTY_ID)).iterator().next().put("name", "INVALID_COMPONENT");
replay(stack, dao, entity, configEntity);
testFactory.createBlueprint(props, null);
}
private class TestBlueprintFactory extends BlueprintFactory {
private Stack stack;
public TestBlueprintFactory(Stack stack) {
this.stack = stack;
}
@Override
protected Stack createStack(Map<String, Object> properties) throws NoSuchStackException {
return stack;
}
}
private void setPrivateField(Object o, String field, Object value) throws Exception {
Class<?> c = o.getClass();
Field f = c.getDeclaredField(field);
f.setAccessible(true);
f.set(o, value);
}
}