You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by js...@apache.org on 2014/11/10 22:32:05 UTC
[06/11] ambari git commit: AMBARI-7175. Add explicit stack service
inheritance
http://git-wip-us.apache.org/repos/asf/ambari/blob/2fc7adec/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/BlueprintEntityTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/BlueprintEntityTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/BlueprintEntityTest.java
index d8c0e29..b965554 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/BlueprintEntityTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/BlueprintEntityTest.java
@@ -22,12 +22,15 @@ import com.google.gson.Gson;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.state.PropertyInfo;
+import org.apache.ambari.server.state.ServiceInfo;
import org.junit.Test;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -83,8 +86,11 @@ public class BlueprintEntityTest {
@Test
public void testValidateConfigurations_clusterConfig() throws Exception {
AmbariMetaInfo metaInfo = createMock(AmbariMetaInfo.class);
+ ServiceInfo service = new ServiceInfo();
+ service.setName("service1");
+
+ List<PropertyInfo> serviceProperties = new ArrayList<PropertyInfo>();
- Map<String, PropertyInfo> requiredProps = new HashMap<String, PropertyInfo>();
PropertyInfo prop = new PropertyInfo();
prop.setFilename("core-site.xml");
prop.setName("super.secret.password");
@@ -93,7 +99,9 @@ public class BlueprintEntityTest {
propertyTypes.add(PropertyInfo.PropertyType.PASSWORD);
prop.setPropertyTypes(propertyTypes);
prop.setValue(null);
- requiredProps.put("super.secret.password", prop);
+ serviceProperties.add(prop);
+ service.getProperties().addAll(serviceProperties);
+ service.getProperties().addAll(serviceProperties);
BlueprintEntity entity = new BlueprintEntity();
entity.setStackName("stackName");
@@ -130,7 +138,7 @@ public class BlueprintEntityTest {
entity.setHostGroups(hostGroupEntities);
expect(metaInfo.getComponentToService("stackName", "version", "component1")).andReturn("service1");
- expect(metaInfo.getRequiredProperties("stackName", "version", "service1")).andReturn(requiredProps);
+ expect(metaInfo.getService("stackName", "version", "service1")).andReturn(service);
replay(metaInfo);
@@ -145,17 +153,20 @@ public class BlueprintEntityTest {
@Test
public void testValidateConfigurations_hostGroupConfig() throws Exception {
AmbariMetaInfo metaInfo = createMock(AmbariMetaInfo.class);
-
- Map<String, PropertyInfo> requiredProps = new HashMap<String, PropertyInfo>();
- PropertyInfo prop = new PropertyInfo();
- prop.setFilename("core-site.xml");
- prop.setName("super.secret.password");
- prop.setRequireInput(true);
+ ServiceInfo service = new ServiceInfo();
+ service.setName("service1");
+
+ List<PropertyInfo> serviceProperties = new ArrayList<PropertyInfo>();
+ PropertyInfo prop1 = new PropertyInfo();
+ prop1.setFilename("core-site.xml");
+ prop1.setName("super.secret.password");
+ prop1.setRequireInput(true);
Set<PropertyInfo.PropertyType> propertyTypes = new HashSet<PropertyInfo.PropertyType>();
propertyTypes.add(PropertyInfo.PropertyType.PASSWORD);
- prop.setPropertyTypes(propertyTypes);
- prop.setValue(null);
- requiredProps.put("super.secret.password", prop);
+ prop1.setPropertyTypes(propertyTypes);
+ prop1.setValue(null);
+ serviceProperties.add(prop1);
+ service.getProperties().addAll(serviceProperties);
BlueprintEntity entity = new BlueprintEntity();
entity.setStackName("stackName");
@@ -193,7 +204,7 @@ public class BlueprintEntityTest {
entity.setHostGroups(hostGroupEntities);
expect(metaInfo.getComponentToService("stackName", "version", "component1")).andReturn("service1");
- expect(metaInfo.getRequiredProperties("stackName", "version", "service1")).andReturn(requiredProps);
+ expect(metaInfo.getService("stackName", "version", "service1")).andReturn(service);
replay(metaInfo);
@@ -208,16 +219,20 @@ public class BlueprintEntityTest {
@Test
public void testValidateConfigurations_negative() throws Exception {
AmbariMetaInfo metaInfo = createMock(AmbariMetaInfo.class);
+ ServiceInfo service = new ServiceInfo();
+ service.setName("service1");
- Map<String, PropertyInfo> requiredProps = new HashMap<String, PropertyInfo>();
- PropertyInfo prop = new PropertyInfo();
- prop.setFilename("core-site.xml");
- prop.setName("super.secret.password");
- prop.setRequireInput(true);
+ List<PropertyInfo> serviceProperties = new ArrayList<PropertyInfo>();
+
+ PropertyInfo prop1 = new PropertyInfo();
+ prop1.setFilename("core-site.xml");
+ prop1.setName("super.secret.password");
+ prop1.setRequireInput(true);
Set<PropertyInfo.PropertyType> propertyTypes = new HashSet<PropertyInfo.PropertyType>();
propertyTypes.add(PropertyInfo.PropertyType.PASSWORD);
- prop.setPropertyTypes(propertyTypes);
- prop.setValue(null);
+ prop1.setPropertyTypes(propertyTypes);
+ prop1.setValue(null);
+ serviceProperties.add(prop1);
PropertyInfo prop2 = new PropertyInfo();
prop2.setFilename("global.xml");
@@ -227,9 +242,9 @@ public class BlueprintEntityTest {
propertyTypes2.add(PropertyInfo.PropertyType.PASSWORD);
prop2.setPropertyTypes(propertyTypes2);
prop2.setValue(" ");
+ serviceProperties.add(prop2);
- requiredProps.put("super.secret.password", prop);
- requiredProps.put("another.super.secret.password", prop2);
+ service.getProperties().addAll(serviceProperties);
BlueprintEntity entity = new BlueprintEntity();
entity.setStackName("stackName");
@@ -266,7 +281,7 @@ public class BlueprintEntityTest {
entity.setHostGroups(hostGroupEntities);
expect(metaInfo.getComponentToService("stackName", "version", "component1")).andReturn("service1");
- expect(metaInfo.getRequiredProperties("stackName", "version", "service1")).andReturn(requiredProps);
+ expect(metaInfo.getService("stackName", "version", "service1")).andReturn(service);
replay(metaInfo);
http://git-wip-us.apache.org/repos/asf/ambari/blob/2fc7adec/ambari-server/src/test/java/org/apache/ambari/server/stack/ComponentModuleTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stack/ComponentModuleTest.java b/ambari-server/src/test/java/org/apache/ambari/server/stack/ComponentModuleTest.java
new file mode 100644
index 0000000..8181cbc
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/stack/ComponentModuleTest.java
@@ -0,0 +1,409 @@
+/**
+ * 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.stack;
+
+import org.apache.ambari.server.state.AutoDeployInfo;
+import org.apache.ambari.server.state.ClientConfigFileDefinition;
+import org.apache.ambari.server.state.CommandScriptDefinition;
+import org.apache.ambari.server.state.ComponentInfo;
+import org.apache.ambari.server.state.CustomCommandDefinition;
+import org.apache.ambari.server.state.DependencyInfo;
+import org.junit.Test;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static org.easymock.EasyMock.createNiceMock;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * ComponentModule unit test case.
+ */
+public class ComponentModuleTest {
+
+ @Test
+ public void testResolve_CommandScript() {
+ CommandScriptDefinition commandScript = new CommandScriptDefinition();
+ ComponentInfo info = new ComponentInfo();
+ ComponentInfo parentInfo = new ComponentInfo();
+
+ // parent has value set, child value is null
+ parentInfo.setCommandScript(commandScript);
+ assertSame(commandScript, resolveComponent(info, parentInfo).getModuleInfo().getCommandScript());
+
+ // child has value set, parent value is null
+ info.setCommandScript(commandScript);
+ parentInfo.setCommandScript(null);
+ assertSame(commandScript, resolveComponent(info, parentInfo).getModuleInfo().getCommandScript());
+
+ // value set in both parent and child; child overwrites
+ CommandScriptDefinition commandScript2 = createNiceMock(CommandScriptDefinition.class);
+ info.setCommandScript(commandScript);
+ parentInfo.setCommandScript(commandScript2);
+ assertSame(commandScript, resolveComponent(info, parentInfo).getModuleInfo().getCommandScript());
+ }
+
+ @Test
+ public void testResolve_DisplayName() {
+ String displayName = "foo";
+
+ ComponentInfo info = new ComponentInfo();
+ ComponentInfo parentInfo = new ComponentInfo();
+
+ // parent has value set, child value is null
+ parentInfo.setDisplayName(displayName);
+ assertEquals(displayName, resolveComponent(info, parentInfo).getModuleInfo().getDisplayName());
+
+ // child has value set, parent value is null
+ info.setDisplayName(displayName);
+ parentInfo.setDisplayName(null);
+ assertEquals(displayName, resolveComponent(info, parentInfo).getModuleInfo().getDisplayName());
+
+ // value set in both parent and child; child overwrites
+ String displayName2 = "foo2";
+ info.setDisplayName(displayName2);
+ parentInfo.setDisplayName(displayName);
+ assertEquals(displayName2, resolveComponent(info, parentInfo).getModuleInfo().getDisplayName());
+ }
+
+ @Test
+ public void testResolve_ClientConfigFiles() {
+ List<ClientConfigFileDefinition> clientConfigs = new ArrayList<ClientConfigFileDefinition>();
+ ClientConfigFileDefinition clientConfig1 = new ClientConfigFileDefinition();
+ clientConfig1.setType("type1");
+ clientConfig1.setDictionaryName("dictName1");
+ clientConfig1.setFileName("filename1");
+ ClientConfigFileDefinition clientConfig2 = new ClientConfigFileDefinition();
+ clientConfig1.setType("type1");
+ clientConfig1.setDictionaryName("dictName1");
+ clientConfig1.setFileName("filename1");
+ clientConfigs.add(clientConfig1);
+ clientConfigs.add(clientConfig2);
+
+ ComponentInfo info = new ComponentInfo();
+ ComponentInfo parentInfo = new ComponentInfo();
+
+ // parent has value set, child value is null
+ parentInfo.setClientConfigFiles(clientConfigs);
+ assertEquals(clientConfigs, resolveComponent(info, parentInfo).getModuleInfo().getClientConfigFiles());
+
+ // child has value set, parent value is null
+ info.setClientConfigFiles(clientConfigs);
+ parentInfo.setClientConfigFiles(null);
+ assertEquals(clientConfigs, resolveComponent(info, parentInfo).getModuleInfo().getClientConfigFiles());
+
+ // value set in both parent and child; child overwrites with no merge
+ List<ClientConfigFileDefinition> clientConfigs2 = new ArrayList<ClientConfigFileDefinition>();
+ ClientConfigFileDefinition clientConfig3 = new ClientConfigFileDefinition();
+ clientConfig3.setType("type1");
+ clientConfig3.setDictionaryName("dictName1");
+ clientConfig3.setFileName("DIFFERENT filename");
+ clientConfigs2.add(clientConfig3);
+
+ info.setClientConfigFiles(clientConfigs2);
+ parentInfo.setClientConfigFiles(clientConfigs);
+ assertEquals(clientConfigs2, resolveComponent(info, parentInfo).getModuleInfo().getClientConfigFiles());
+ }
+
+ @Test
+ public void testResolve_Category() {
+ String category = "foo";
+
+ ComponentInfo info = new ComponentInfo();
+ ComponentInfo parentInfo = new ComponentInfo();
+
+ // parent has value set, child value is null
+ parentInfo.setCategory(category);
+ assertEquals(category, resolveComponent(info, parentInfo).getModuleInfo().getCategory());
+
+ // child has value set, parent value is null
+ info.setCategory(category);
+ parentInfo.setCategory(null);
+ assertEquals(category, resolveComponent(info, parentInfo).getModuleInfo().getCategory());
+
+ // value set in both parent and child; child overwrites
+ String category2 = "foo2";
+ info.setCategory(category2);
+ parentInfo.setCategory(category);
+ assertEquals(category2, resolveComponent(info, parentInfo).getModuleInfo().getCategory());
+ }
+
+ @Test
+ public void testResolve_Cardinality() {
+ String cardinality = "foo";
+
+ ComponentInfo info = new ComponentInfo();
+ ComponentInfo parentInfo = new ComponentInfo();
+
+ // parent has value set, child value is null
+ parentInfo.setCardinality(cardinality);
+ assertEquals(cardinality, resolveComponent(info, parentInfo).getModuleInfo().getCardinality());
+
+ // child has value set, parent value is null
+ info.setCardinality(cardinality);
+ parentInfo.setCardinality(null);
+ assertEquals(cardinality, resolveComponent(info, parentInfo).getModuleInfo().getCardinality());
+
+ // value set in both parent and child; child overwrites
+ String cardinality2 = "foo2";
+ info.setCardinality(cardinality2);
+ parentInfo.setCardinality(cardinality);
+ assertEquals(cardinality2, resolveComponent(info, parentInfo).getModuleInfo().getCardinality());
+ }
+
+ @Test
+ public void testResolve_AutoDeploy() {
+ AutoDeployInfo autoDeployInfo = new AutoDeployInfo();
+ autoDeployInfo.setEnabled(true);
+ autoDeployInfo.setCoLocate("foo/bar");
+ ComponentInfo info = new ComponentInfo();
+ ComponentInfo parentInfo = new ComponentInfo();
+
+ // parent has value set, child value is null
+ parentInfo.setAutoDeploy(autoDeployInfo);
+ assertEquals(autoDeployInfo, resolveComponent(info, parentInfo).getModuleInfo().getAutoDeploy());
+
+ // child has value set, parent value is null
+ info.setAutoDeploy(autoDeployInfo);
+ parentInfo.setAutoDeploy(null);
+ assertEquals(autoDeployInfo, resolveComponent(info, parentInfo).getModuleInfo().getAutoDeploy());
+
+ // value set in both parent and child; child overwrites
+ AutoDeployInfo autoDeployInfo2 = new AutoDeployInfo();
+ info.setAutoDeploy(autoDeployInfo);
+ parentInfo.setAutoDeploy(autoDeployInfo2);
+ assertEquals(autoDeployInfo, resolveComponent(info, parentInfo).getModuleInfo().getAutoDeploy());
+ }
+
+
+ @Test
+ public void testResolve_Dependencies() {
+ List<DependencyInfo> dependencies = new ArrayList<DependencyInfo>();
+ DependencyInfo dependency1 = new DependencyInfo();
+ dependency1.setName("service/one");
+ DependencyInfo dependency2 = new DependencyInfo();
+ dependency2.setName("service/two");
+ dependencies.add(dependency1);
+ dependencies.add(dependency2);
+
+ ComponentInfo info = new ComponentInfo();
+ ComponentInfo parentInfo = new ComponentInfo();
+
+ // parent has value set, child value is null
+ parentInfo.setDependencies(dependencies);
+ assertEquals(dependencies, resolveComponent(info, parentInfo).getModuleInfo().getDependencies());
+
+ // child has value set, parent value is null
+ info.setDependencies(dependencies);
+ parentInfo.setDependencies(null);
+ assertEquals(dependencies, resolveComponent(info, parentInfo).getModuleInfo().getDependencies());
+
+ // value set in both parent and child; merge parent and child
+ //todo: currently there is no way to remove an inherited dependency
+ List<DependencyInfo> dependencies2 = new ArrayList<DependencyInfo>();
+ DependencyInfo dependency3 = new DependencyInfo();
+ dependency3.setName("service/two");
+ DependencyInfo dependency4 = new DependencyInfo();
+ dependency4.setName("service/four");
+ dependencies2.add(dependency3);
+ dependencies2.add(dependency4);
+
+ info.setDependencies(dependencies2);
+ parentInfo.setDependencies(dependencies);
+
+ List<DependencyInfo> resolvedDependencies = resolveComponent(info, parentInfo).getModuleInfo().getDependencies();
+ assertEquals(3, resolvedDependencies.size());
+ assertTrue(resolvedDependencies.contains(dependency1));
+ assertTrue(resolvedDependencies.contains(dependency3));
+ assertTrue(resolvedDependencies.contains(dependency4));
+ }
+
+ @Test
+ public void testResolve_CustomCommands() throws Exception {
+ List<CustomCommandDefinition> commands = new ArrayList<CustomCommandDefinition>();
+ CustomCommandDefinition command1 = new CustomCommandDefinition();
+ setPrivateField(command1, "name", "one");
+ CustomCommandDefinition command2 = new CustomCommandDefinition();
+ setPrivateField(command2, "name", "two");
+ commands.add(command1);
+ commands.add(command2);
+
+ ComponentInfo info = new ComponentInfo();
+ ComponentInfo parentInfo = new ComponentInfo();
+
+ // parent has value set, child value is null
+ parentInfo.setCustomCommands(commands);
+ assertEquals(commands, resolveComponent(info, parentInfo).getModuleInfo().getCustomCommands());
+
+ // child has value set, parent value is null
+ info.setCustomCommands(commands);
+ parentInfo.setCustomCommands(null);
+ assertEquals(commands, resolveComponent(info, parentInfo).getModuleInfo().getCustomCommands());
+
+ // value set in both parent and child; merge parent and child
+ //todo: currently there is no way to remove an inherited command
+ List<CustomCommandDefinition> commands2 = new ArrayList<CustomCommandDefinition>();
+ CustomCommandDefinition command3 = new CustomCommandDefinition();
+ // override command 2
+ setPrivateField(command3, "name", "two");
+ CustomCommandDefinition command4 = new CustomCommandDefinition();
+ setPrivateField(command4, "name", "four");
+ commands2.add(command3);
+ commands2.add(command4);
+
+ info.setCustomCommands(commands2);
+ parentInfo.setCustomCommands(commands);
+
+ List<CustomCommandDefinition> resolvedCommands = resolveComponent(info, parentInfo).getModuleInfo().getCustomCommands();
+ assertEquals(3, resolvedCommands.size());
+ assertTrue(resolvedCommands.contains(command1));
+ assertTrue(resolvedCommands.contains(command3));
+ assertTrue(resolvedCommands.contains(command4));
+ }
+
+ @Test
+ // merging of config dependencies is different than other non-module merges in that the collections aren't
+ // merged if any config dependency is specified in the child. So, the merged result is either the child
+ // dependencies or if null, the parent dependencies.
+ public void testResolve_ConfigDependencies() {
+ List<String> dependencies = new ArrayList<String>();
+ String dependency1 = "one";
+ String dependency2 = "two";
+ dependencies.add(dependency1);
+ dependencies.add(dependency2);
+
+ ComponentInfo info = new ComponentInfo();
+ ComponentInfo parentInfo = new ComponentInfo();
+
+ // parent has value set, child value is null
+ parentInfo.setConfigDependencies(dependencies);
+ assertEquals(dependencies, resolveComponent(info, parentInfo).getModuleInfo().getConfigDependencies());
+
+ // child has value set, parent value is null
+ info.setConfigDependencies(dependencies);
+ parentInfo.setConfigDependencies(null);
+ assertEquals(dependencies, resolveComponent(info, parentInfo).getModuleInfo().getConfigDependencies());
+
+ // value set in both parent and child; merge parent and child
+ List<String> dependencies2 = new ArrayList<String>();
+ String dependency3 = "two";
+ String dependency4 = "four";
+ dependencies2.add(dependency3);
+ dependencies2.add(dependency4);
+
+ info.setConfigDependencies(dependencies2);
+ parentInfo.setConfigDependencies(dependencies);
+
+ List<String> resolvedDependencies = resolveComponent(info, parentInfo).getModuleInfo().getConfigDependencies();
+ assertEquals(2, resolvedDependencies.size());
+ assertTrue(resolvedDependencies.contains(dependency3));
+ assertTrue(resolvedDependencies.contains(dependency4));
+ }
+
+ @Test
+ // merging of "client to update configs", whatever that means, is different than most other non-module merges
+ // in that the collections aren't merged if any "client to update configs" is specified in the child.
+ // So, the merged result is either the child collection or if null, the parent collection.
+ public void testResolve_ClientToUpdateConfigs() {
+ List<String> clientsToUpdate = new ArrayList<String>();
+ String client1 = "one";
+ String client2 = "two";
+ clientsToUpdate.add(client1);
+ clientsToUpdate.add(client2);
+
+ ComponentInfo info = new ComponentInfo();
+ ComponentInfo parentInfo = new ComponentInfo();
+
+ // parent has value set, child value is null
+ parentInfo.setClientsToUpdateConfigs(clientsToUpdate);
+ assertEquals(clientsToUpdate, resolveComponent(info, parentInfo).getModuleInfo().getClientsToUpdateConfigs());
+
+ // child has value set, parent value is null
+ info.setClientsToUpdateConfigs(clientsToUpdate);
+ parentInfo.setClientsToUpdateConfigs(null);
+ assertEquals(clientsToUpdate, resolveComponent(info, parentInfo).getModuleInfo().getClientsToUpdateConfigs());
+
+ // value set in both parent and child; merge parent and child
+ List<String> clientsToUpdate2 = new ArrayList<String>();
+ String client3 = "two";
+ String client4 = "four";
+ clientsToUpdate2.add(client3);
+ clientsToUpdate2.add(client4);
+
+ info.setClientsToUpdateConfigs(clientsToUpdate2);
+ parentInfo.setClientsToUpdateConfigs(clientsToUpdate);
+
+ List<String> resolvedClientsToUpdate = resolveComponent(info, parentInfo).getModuleInfo().getClientsToUpdateConfigs();
+ assertEquals(2, resolvedClientsToUpdate.size());
+ assertTrue(resolvedClientsToUpdate.contains(client3));
+ assertTrue(resolvedClientsToUpdate.contains(client4));
+ }
+
+ @Test
+ public void testGetId() {
+ ComponentInfo info = new ComponentInfo();
+ info.setName("foo");
+
+ ComponentModule component = new ComponentModule(info);
+ assertEquals("foo", component.getId());
+ }
+
+ @Test
+ public void testIsDeleted() {
+ // default value
+ ComponentInfo info = new ComponentInfo();
+ info.setName("foo");
+
+ ComponentModule component = new ComponentModule(info);
+ assertFalse(component.isDeleted());
+
+ // explicit value
+ info = new ComponentInfo();
+ info.setName("foo");
+ info.setDeleted(true);
+
+ component = new ComponentModule(info);
+ assertTrue(component.isDeleted());
+ }
+
+ private ComponentModule resolveComponent(ComponentInfo info, ComponentInfo parentInfo) {
+ info.setName("FOO");
+ parentInfo.setName("FOO");
+
+ ComponentModule component = new ComponentModule(info);
+ ComponentModule parentComponent = new ComponentModule(parentInfo);
+
+ component.resolve(parentComponent, Collections.<String, StackModule>emptyMap());
+
+ return component;
+ }
+
+ 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);
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/2fc7adec/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java b/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java
new file mode 100644
index 0000000..225213f
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java
@@ -0,0 +1,983 @@
+/**
+ * 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.stack;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.state.CommandScriptDefinition;
+import org.apache.ambari.server.state.ComponentInfo;
+import org.apache.ambari.server.state.CustomCommandDefinition;
+import org.apache.ambari.server.state.PropertyInfo;
+import org.apache.ambari.server.state.ServiceInfo;
+import org.apache.ambari.server.state.ServiceOsSpecific;
+import org.junit.Test;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.createStrictMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * ServiceModule unit tests.
+ */
+public class ServiceModuleTest {
+
+ @Test
+ public void testResolve_Comment() throws Exception {
+ String comment = "test comment";
+
+ // comment specified in child only
+ ServiceInfo info = new ServiceInfo();
+ ServiceInfo parentInfo = new ServiceInfo();
+ info.setComment(comment);
+
+ ServiceModule service = resolveService(info, parentInfo);
+ assertEquals(comment, service.getModuleInfo().getComment());
+
+ // comment specified in parent only
+ info.setComment(null);
+ parentInfo.setComment(comment);
+
+ service = resolveService(info, parentInfo);
+ assertEquals(comment, service.getModuleInfo().getComment());
+
+ // set in both
+ info.setComment(comment);
+ parentInfo.setComment("other comment");
+
+ service = resolveService(info, parentInfo);
+ assertEquals(comment, service.getModuleInfo().getComment());
+ }
+
+ @Test
+ public void testResolve_DisplayName() throws Exception {
+ String displayName = "test_display_name";
+
+ // specified in child only
+ ServiceInfo info = new ServiceInfo();
+ ServiceInfo parentInfo = new ServiceInfo();
+ info.setDisplayName(displayName);
+
+ ServiceModule service = resolveService(info, parentInfo);
+ assertEquals(displayName, service.getModuleInfo().getDisplayName());
+
+ // specified in parent only
+ info.setDisplayName(null);
+ parentInfo.setDisplayName(displayName);
+
+ service = resolveService(info, parentInfo);
+ assertEquals(displayName, service.getModuleInfo().getDisplayName());
+
+ // specified in both
+ info.setDisplayName(displayName);
+ parentInfo.setDisplayName("other display name");
+
+ service = resolveService(info, parentInfo);
+ assertEquals(displayName, service.getModuleInfo().getDisplayName());
+ }
+
+ @Test
+ public void testResolve_RequiredServices() throws Exception {
+ List<String> requiredServices = new ArrayList<String>();
+ requiredServices.add("foo");
+ requiredServices.add("bar");
+
+ // specified in child only
+ ServiceInfo info = new ServiceInfo();
+ ServiceInfo parentInfo = new ServiceInfo();
+ info.setRequiredServices(requiredServices);
+
+ ServiceModule service = resolveService(info, parentInfo);
+ assertEquals(requiredServices, service.getModuleInfo().getRequiredServices());
+
+ // specified in parent only
+ info.setRequiredServices(null);
+ parentInfo.setRequiredServices(requiredServices);
+
+ service = resolveService(info, parentInfo);
+ assertEquals(requiredServices, service.getModuleInfo().getRequiredServices());
+
+ // specified in both
+ info.setRequiredServices(requiredServices);
+ parentInfo.setRequiredServices(Collections.singletonList("other"));
+
+ service = resolveService(info, parentInfo);
+ assertEquals(requiredServices, service.getModuleInfo().getRequiredServices());
+
+ // not set in either
+ info.setRequiredServices(null);
+ parentInfo.setRequiredServices(null);
+
+ service = resolveService(info, parentInfo);
+ assertTrue(service.getModuleInfo().getRequiredServices().isEmpty());
+ }
+
+ @Test
+ public void testResolve_RestartRequiredAfterChange() throws Exception {
+ Boolean isRestartRequired = true;
+
+ // specified in child only
+ ServiceInfo info = new ServiceInfo();
+ ServiceInfo parentInfo = new ServiceInfo();
+ info.setRestartRequiredAfterChange(isRestartRequired);
+
+ ServiceModule service = resolveService(info, parentInfo);
+ assertEquals(isRestartRequired, service.getModuleInfo().isRestartRequiredAfterChange());
+
+ // specified in parent only
+ info.setRestartRequiredAfterChange(null);
+ parentInfo.setRestartRequiredAfterChange(isRestartRequired);
+
+ service = resolveService(info, parentInfo);
+ assertEquals(isRestartRequired, service.getModuleInfo().isRestartRequiredAfterChange());
+
+ // specified in both
+ info.setRestartRequiredAfterChange(isRestartRequired);
+ parentInfo.setRestartRequiredAfterChange(false);
+
+ service = resolveService(info, parentInfo);
+ assertEquals(isRestartRequired, service.getModuleInfo().isRestartRequiredAfterChange());
+ }
+
+ @Test
+ public void testResolve_MonitoringService() throws Exception {
+ Boolean isMonitoringService = true;
+
+ // specified in child only
+ ServiceInfo info = new ServiceInfo();
+ ServiceInfo parentInfo = new ServiceInfo();
+ info.setMonitoringService(isMonitoringService);
+
+ ServiceModule service = resolveService(info, parentInfo);
+ assertEquals(isMonitoringService, service.getModuleInfo().isMonitoringService());
+
+ // specified in parent only
+ info.setMonitoringService(null);
+ parentInfo.setMonitoringService(isMonitoringService);
+
+ service = resolveService(info, parentInfo);
+ assertEquals(isMonitoringService, service.getModuleInfo().isMonitoringService());
+
+ // specified in both
+ info.setMonitoringService(isMonitoringService);
+ parentInfo.setMonitoringService(false);
+
+ service = resolveService(info, parentInfo);
+ assertEquals(isMonitoringService, service.getModuleInfo().isMonitoringService());
+ }
+
+ @Test
+ public void testResolve_OsSpecifics() throws Exception {
+ Map<String, ServiceOsSpecific> osSpecifics = new HashMap<String, ServiceOsSpecific>();
+ osSpecifics.put("foo", new ServiceOsSpecific());
+
+ // specified in child only
+ ServiceInfo info = new ServiceInfo();
+ ServiceInfo parentInfo = new ServiceInfo();
+ info.setOsSpecifics(osSpecifics);
+
+ ServiceModule service = resolveService(info, parentInfo);
+ assertEquals(osSpecifics, service.getModuleInfo().getOsSpecifics());
+
+ // specified in parent only
+ info.setOsSpecifics(null);
+ parentInfo.setOsSpecifics(osSpecifics);
+
+ service = resolveService(info, parentInfo);
+ assertEquals(osSpecifics, service.getModuleInfo().getOsSpecifics());
+
+ // specified in both
+ Map<String, ServiceOsSpecific> osSpecifics2 = new HashMap<String, ServiceOsSpecific>();
+ osSpecifics.put("bar", new ServiceOsSpecific());
+
+ info.setOsSpecifics(osSpecifics);
+ parentInfo.setOsSpecifics(osSpecifics2);
+
+ service = resolveService(info, parentInfo);
+ assertEquals(osSpecifics, service.getModuleInfo().getOsSpecifics());
+ }
+
+ @Test
+ public void testResolve_CommandScript() throws Exception {
+ CommandScriptDefinition commandScript = new CommandScriptDefinition();
+
+ // specified in child only
+ ServiceInfo info = new ServiceInfo();
+ ServiceInfo parentInfo = new ServiceInfo();
+ info.setCommandScript(commandScript);
+
+ ServiceModule service = resolveService(info, parentInfo);
+ assertEquals(commandScript, service.getModuleInfo().getCommandScript());
+
+ // specified in parent only
+ info.setCommandScript(null);
+ parentInfo.setCommandScript(commandScript);
+
+ service = resolveService(info, parentInfo);
+ assertEquals(commandScript, service.getModuleInfo().getCommandScript());
+
+ // specified in both
+ CommandScriptDefinition commandScript2 = new CommandScriptDefinition();
+
+ info.setCommandScript(commandScript);
+ parentInfo.setCommandScript(commandScript2);
+
+ service = resolveService(info, parentInfo);
+ assertEquals(commandScript, service.getModuleInfo().getCommandScript());
+ }
+
+ @Test
+ public void testResolve_ServicePackageFolder() throws Exception {
+ String servicePackageFolder = "packageDir";
+
+ // specified in child only
+ ServiceInfo info = new ServiceInfo();
+ ServiceInfo parentInfo = new ServiceInfo();
+
+ ServiceModule child = createServiceModule(info);
+ ServiceModule parent = createServiceModule(parentInfo);
+
+ // set in the module constructor from a value obtained from service directory
+ assertEquals("packageDir", child.getModuleInfo().getServicePackageFolder());
+ parent.getModuleInfo().setServicePackageFolder(null);
+
+ resolveService(child, parent);
+ assertEquals(servicePackageFolder, child.getModuleInfo().getServicePackageFolder());
+
+ // specified in parent only
+ child = createServiceModule(info);
+ parent = createServiceModule(parentInfo);
+ parent.getModuleInfo().setServicePackageFolder(servicePackageFolder);
+ child.getModuleInfo().setServicePackageFolder(null);
+
+ resolveService(child, parent);
+ assertEquals(servicePackageFolder, child.getModuleInfo().getServicePackageFolder());
+
+ // specified in both
+ child = createServiceModule(info);
+ parent = createServiceModule(parentInfo);
+ parent.getModuleInfo().setServicePackageFolder("someOtherDir");
+ child.getModuleInfo().setServicePackageFolder(servicePackageFolder);
+
+ resolveService(child, parent);
+ assertEquals(servicePackageFolder, child.getModuleInfo().getServicePackageFolder());
+ }
+
+ @Test
+ public void testResolve_MetricsFile() throws Exception {
+ File metricsFile = new File("testMetricsFile");
+
+ // specified in child only
+ ServiceInfo info = new ServiceInfo();
+ ServiceInfo parentInfo = new ServiceInfo();
+
+ ServiceModule child = createServiceModule(info);
+ ServiceModule parent = createServiceModule(parentInfo);
+
+ // set in the module constructor from a value obtained from service directory which is mocked
+ assertEquals(metricsFile, child.getModuleInfo().getMetricsFile());
+ parent.getModuleInfo().setMetricsFile(null);
+
+ resolveService(child, parent);
+ assertEquals(metricsFile, child.getModuleInfo().getMetricsFile());
+
+ // specified in parent only
+ child = createServiceModule(info);
+ parent = createServiceModule(parentInfo);
+ parent.getModuleInfo().setMetricsFile(metricsFile);
+ child.getModuleInfo().setMetricsFile(null);
+
+ resolveService(child, parent);
+ assertEquals(metricsFile, child.getModuleInfo().getMetricsFile());
+
+ // specified in both
+ child = createServiceModule(info);
+ parent = createServiceModule(parentInfo);
+ parent.getModuleInfo().setMetricsFile(new File("someOtherDir"));
+ child.getModuleInfo().setMetricsFile(metricsFile);
+
+ resolveService(child, parent);
+ assertEquals(metricsFile, child.getModuleInfo().getMetricsFile());
+ }
+
+ @Test
+ public void testResolve_AlertsFile() throws Exception {
+ File alertsFile = new File("testAlertsFile");
+
+ // specified in child only
+ ServiceInfo info = new ServiceInfo();
+ ServiceInfo parentInfo = new ServiceInfo();
+
+ ServiceModule child = createServiceModule(info);
+ ServiceModule parent = createServiceModule(parentInfo);
+
+ // set in the module constructor from a value obtained from service directory which is mocked
+ assertEquals(alertsFile, child.getModuleInfo().getAlertsFile());
+ parent.getModuleInfo().setAlertsFile(null);
+
+ resolveService(child, parent);
+ assertEquals(alertsFile, child.getModuleInfo().getAlertsFile());
+
+ // specified in parent only
+ child = createServiceModule(info);
+ parent = createServiceModule(parentInfo);
+ parent.getModuleInfo().setAlertsFile(alertsFile);
+ child.getModuleInfo().setAlertsFile(null);
+
+ resolveService(child, parent);
+ assertEquals(alertsFile, child.getModuleInfo().getAlertsFile());
+
+ // specified in both
+ child = createServiceModule(info);
+ parent = createServiceModule(parentInfo);
+ parent.getModuleInfo().setAlertsFile(new File("someOtherDir"));
+ child.getModuleInfo().setAlertsFile(alertsFile);
+
+ resolveService(child, parent);
+ assertEquals(alertsFile, child.getModuleInfo().getAlertsFile());
+ }
+
+ @Test
+ public void testResolve_CustomCommands() throws Exception {
+ List<CustomCommandDefinition> customCommands = new ArrayList<CustomCommandDefinition>();
+ CustomCommandDefinition cmd1 = new CustomCommandDefinition();
+ setPrivateField(cmd1, "name", "cmd1");
+ setPrivateField(cmd1, "background", false);
+ CustomCommandDefinition cmd2 = new CustomCommandDefinition();
+ setPrivateField(cmd2, "name", "cmd2");
+ customCommands.add(cmd1);
+ customCommands.add(cmd2);
+
+ // specified in child only
+ ServiceInfo info = new ServiceInfo();
+ ServiceInfo parentInfo = new ServiceInfo();
+ info.setCustomCommands(customCommands);
+
+ ServiceModule service = resolveService(info, parentInfo);
+ assertEquals(customCommands, service.getModuleInfo().getCustomCommands());
+
+ // specified in parent only
+ info.setCustomCommands(null);
+ parentInfo.setCustomCommands(customCommands);
+
+ service = resolveService(info, parentInfo);
+ assertEquals(customCommands, service.getModuleInfo().getCustomCommands());
+
+ // specified in both
+ List<CustomCommandDefinition> parentCustomCommands = new ArrayList<CustomCommandDefinition>();
+ CustomCommandDefinition cmd3 = new CustomCommandDefinition();
+ setPrivateField(cmd3, "name", "cmd1");
+ setPrivateField(cmd3, "background", true);
+ CustomCommandDefinition cmd4 = new CustomCommandDefinition();
+ setPrivateField(cmd4, "name", "cmd4");
+ parentCustomCommands.add(cmd3);
+ parentCustomCommands.add(cmd4);
+
+ info.setCustomCommands(customCommands);
+ parentInfo.setCustomCommands(parentCustomCommands);
+
+ service = resolveService(info, parentInfo);
+ Collection<CustomCommandDefinition> mergedCommands = service.getModuleInfo().getCustomCommands();
+ assertEquals(3, mergedCommands.size());
+ assertTrue(mergedCommands.contains(cmd2));
+ assertTrue(mergedCommands.contains(cmd3));
+ assertTrue(mergedCommands.contains(cmd4));
+
+ // not set in either
+ info.setCustomCommands(null);
+ parentInfo.setCustomCommands(null);
+
+ service = resolveService(info, parentInfo);
+ assertTrue(service.getModuleInfo().getCustomCommands().isEmpty());
+ }
+
+ @Test
+ public void testResolve_ConfigDependencies() throws Exception {
+ List<String> configDependencies = new ArrayList<String>();
+ configDependencies.add("foo");
+ configDependencies.add("bar");
+
+ // specified in child only
+ ServiceInfo info = new ServiceInfo();
+ ServiceInfo parentInfo = new ServiceInfo();
+ info.setConfigDependencies(configDependencies);
+
+ ServiceModule service = resolveService(info, parentInfo);
+ assertEquals(configDependencies, service.getModuleInfo().getConfigDependencies());
+
+ // specified in parent only
+ info.setConfigDependencies(null);
+ parentInfo.setConfigDependencies(configDependencies);
+
+ service = resolveService(info, parentInfo);
+ assertEquals(configDependencies, service.getModuleInfo().getConfigDependencies());
+
+ // specified in both
+ List<String> parentCustomCommands = new ArrayList<String>();
+ parentCustomCommands.add("bar");
+ parentCustomCommands.add("other");
+
+ info.setConfigDependencies(configDependencies);
+ parentInfo.setConfigDependencies(parentCustomCommands);
+
+ service = resolveService(info, parentInfo);
+ Collection<String> mergedConfigDependencies = service.getModuleInfo().getConfigDependencies();
+ assertEquals(3, mergedConfigDependencies.size());
+ assertTrue(mergedConfigDependencies.contains("foo"));
+ assertTrue(mergedConfigDependencies.contains("bar"));
+ assertTrue(mergedConfigDependencies.contains("other"));
+
+ // not set in either
+ info.setConfigDependencies(null);
+ parentInfo.setConfigDependencies(null);
+
+ service = resolveService(info, parentInfo);
+ assertTrue(service.getModuleInfo().getConfigDependencies().isEmpty());
+ }
+
+ @Test
+ public void testResolve_Components() throws Exception {
+ // resolve should merge the child component collections
+ // components 1, 2 and XX are set on the parent
+ // components 1, 4 and XX are set on the child
+ // component XX is marked for delete on the child and shouldn't be included
+ // component 1 should be merged
+ // both non-intersecting components 2 and 4 should be included
+ ComponentInfo info1 = new ComponentInfo();
+ info1.setName("1");
+ info1.setCardinality("ALL");
+ ComponentInfo info2 = new ComponentInfo();
+ info2.setName("2");
+ ComponentInfo XX = new ComponentInfo();
+ XX.setName("XX");
+
+ ComponentInfo info3 = new ComponentInfo();
+ // overlaps with info1
+ info3.setName("1");
+ info3.setCategory("category");
+ ComponentInfo info4 = new ComponentInfo();
+ info4.setName("4");
+ ComponentInfo info5 = new ComponentInfo();
+ // overlaps with componentToBeDeleted
+ info5.setName("XX");
+ info5.setDeleted(true);
+
+ ServiceInfo info = new ServiceInfo();
+ ServiceInfo parentInfo = new ServiceInfo();
+
+ //todo: getComponents() should return a protective copy, but for now there is no set/add method
+ List<ComponentInfo> childComponents = info.getComponents();
+ childComponents.add(info3);
+ childComponents.add(info4);
+ childComponents.add(info5);
+
+ List<ComponentInfo> parentComponents = parentInfo.getComponents();
+ parentComponents.add(info1);
+ parentComponents.add(info2);
+
+ ServiceModule child = createServiceModule(info);
+ ServiceModule parent = createServiceModule(parentInfo);
+
+ resolveService(child, parent);
+
+ List<ComponentInfo> components = child.getModuleInfo().getComponents();
+ assertEquals(3, components.size());
+
+ Map<String, ComponentInfo> mergedComponents = new HashMap<String, ComponentInfo>();
+ for (ComponentInfo component : components) {
+ mergedComponents.put(component.getName(), component);
+ }
+ assertTrue(mergedComponents.containsKey("1"));
+ assertTrue(mergedComponents.containsKey("2"));
+ assertTrue(mergedComponents.containsKey("4"));
+
+ // ensure that overlapping components were merged.
+ //don't test all properties, this is done in ComponentModuleTest
+ assertEquals("ALL", mergedComponents.get("1").getCardinality());
+ assertEquals("category", mergedComponents.get("1").getCategory());
+ }
+
+ @Test
+ public void testResolve_Configuration__properties() throws Exception {
+ ServiceInfo info = new ServiceInfo();
+ ServiceInfo parentInfo = new ServiceInfo();
+
+ // child configurations
+ //FOO
+ Collection<PropertyInfo> childFooProperties = new ArrayList<PropertyInfo>();
+ PropertyInfo childProp1 = new PropertyInfo();
+ childProp1.setName("childName1");
+ childProp1.setValue("childVal1");
+ childFooProperties.add(childProp1);
+
+ //BAR : Doesn't inherit parents BAR due to attribute Supports.DO_NOT_EXTEND
+ Collection<PropertyInfo> childBarProperties = new ArrayList<PropertyInfo>();
+ PropertyInfo childProp2 = new PropertyInfo();
+ childProp2.setName("childName2");
+ childProp2.setValue("childVal2");
+ childBarProperties.add(childProp2);
+
+ // add attributes for BAR
+ Map<String, String> attributes = new HashMap<String, String>();
+ attributes.put(ConfigurationInfo.Supports.DO_NOT_EXTEND.getXmlAttributeName(), "true");
+
+ // create child config modules
+ ConfigurationModule childConfigModule1 = createConfigurationModule("FOO", childFooProperties);
+ ConfigurationModule childConfigModule2 = createConfigurationModule("BAR", childBarProperties, attributes);
+ Collection<ConfigurationModule> childModules = new ArrayList<ConfigurationModule>();
+ childModules.add(childConfigModule1);
+ childModules.add(childConfigModule2);
+
+ // parent configurations
+ //FOO
+ Collection<PropertyInfo> parentFooProperties = new ArrayList<PropertyInfo>();
+ PropertyInfo parentProp1 = new PropertyInfo();
+ parentProp1.setName("parentName1");
+ parentProp1.setValue("parentVal1");
+ parentFooProperties.add(parentProp1);
+ PropertyInfo parentProp12 = new PropertyInfo();
+ // overwritten by child
+ parentProp12.setName("childName1");
+ parentProp12.setValue("parentVal1");
+ parentFooProperties.add(parentProp12);
+
+ //BAR
+ Collection<PropertyInfo> parentBarProperties = new ArrayList<PropertyInfo>();
+ PropertyInfo parentProp2 = new PropertyInfo();
+ parentProp2.setName("parentName2");
+ parentProp2.setValue("parentVal2");
+ parentBarProperties.add(parentProp2);
+
+ //OTHER
+ Collection<PropertyInfo> parentOtherProperties = new ArrayList<PropertyInfo>();
+ PropertyInfo parentProp3 = new PropertyInfo();
+ parentProp3.setName("parentName3");
+ parentProp3.setValue("parentVal3");
+ parentOtherProperties.add(parentProp3);
+
+ // create parent config modules
+ ConfigurationModule parentConfigModule1 = createConfigurationModule("FOO", parentFooProperties);
+ ConfigurationModule parentConfigModule2 = createConfigurationModule("BAR", parentBarProperties);
+ ConfigurationModule parentConfigModule3 = createConfigurationModule("OTHER", parentOtherProperties);
+ Collection<ConfigurationModule> parentModules = new ArrayList<ConfigurationModule>();
+ parentModules.add(parentConfigModule1);
+ parentModules.add(parentConfigModule2);
+ parentModules.add(parentConfigModule3);
+
+ // create service modules
+ ServiceModule child = createServiceModule(info, childModules);
+ ServiceModule parent = createServiceModule(parentInfo, parentModules);
+
+ // resolve child with parent
+ resolveService(child, parent);
+
+ // assertions
+ List<PropertyInfo> mergedProperties = child.getModuleInfo().getProperties();
+ assertEquals(4, mergedProperties.size());
+
+ Map<String, PropertyInfo> mergedPropertyMap = new HashMap<String, PropertyInfo>();
+ for (PropertyInfo prop : mergedProperties) {
+ mergedPropertyMap.put(prop.getName(), prop);
+ }
+
+ // filename is null for all props because that is set in ConfigurationDirectory which is mocked
+ assertEquals("childVal1", mergedPropertyMap.get("childName1").getValue());
+ assertEquals("childVal2", mergedPropertyMap.get("childName2").getValue());
+ assertEquals("parentVal1", mergedPropertyMap.get("parentName1").getValue());
+ assertEquals("parentVal3", mergedPropertyMap.get("parentName3").getValue());
+
+ Map<String, Map<String, Map<String, String>>> childAttributes = child.getModuleInfo().getConfigTypeAttributes();
+ Map<String, Map<String, Map<String, String>>> parentAttributes = parent.getModuleInfo().getConfigTypeAttributes();
+
+ assertEquals(3, childAttributes.size());
+ assertAttributes(childAttributes.get("FOO"), Collections.<String, String>emptyMap());
+ assertAttributes(childAttributes.get("BAR"), attributes);
+ assertAttributes(childAttributes.get("OTHER"), Collections.<String, String>emptyMap());
+
+ assertEquals(3, parentAttributes.size());
+ assertAttributes(parentAttributes.get("FOO"), Collections.<String, String>emptyMap());
+ assertAttributes(parentAttributes.get("BAR"), Collections.<String, String>emptyMap());
+ assertAttributes(parentAttributes.get("OTHER"), Collections.<String, String>emptyMap());
+ }
+
+ @Test
+ public void testResolve_Configuration__attributes() throws Exception {
+ ServiceInfo info = new ServiceInfo();
+ ServiceInfo parentInfo = new ServiceInfo();
+
+ // child configurations
+ //FOO
+ Collection<PropertyInfo> childFooProperties = new ArrayList<PropertyInfo>();
+ PropertyInfo childProp1 = new PropertyInfo();
+ childProp1.setName("childName1");
+ childProp1.setValue("childVal1");
+ childFooProperties.add(childProp1);
+
+ // add attributes for parent FOO
+ Map<String, String> childFooAttributes = new HashMap<String, String>();
+ // override parents value
+ childFooAttributes.put(ConfigurationInfo.Supports.ADDING_FORBIDDEN.getXmlAttributeName(), "false");
+
+ // create child config modules
+ ConfigurationModule childConfigModule1 = createConfigurationModule("FOO", childFooProperties, childFooAttributes);
+ Collection<ConfigurationModule> childModules = new ArrayList<ConfigurationModule>();
+ childModules.add(childConfigModule1);
+
+ // parent configurations
+ //FOO
+ Collection<PropertyInfo> parentFooProperties = new ArrayList<PropertyInfo>();
+ PropertyInfo parentProp1 = new PropertyInfo();
+ parentProp1.setName("parentName1");
+ parentProp1.setValue("parentVal1");
+ parentFooProperties.add(parentProp1);
+
+ // add attributes for parent FOO
+ Map<String, String> parentFooAttributes = new HashMap<String, String>();
+ // child will inherit
+ parentFooAttributes.put(ConfigurationInfo.Supports.FINAL.getXmlAttributeName(), "true");
+ // child will override
+ parentFooAttributes.put(ConfigurationInfo.Supports.ADDING_FORBIDDEN.getXmlAttributeName(), "true");
+
+ //BAR
+ Collection<PropertyInfo> parentBarProperties = new ArrayList<PropertyInfo>();
+ PropertyInfo parentProp2 = new PropertyInfo();
+ parentProp2.setName("parentName2");
+ parentProp2.setValue("parentVal2");
+ parentBarProperties.add(parentProp2);
+
+
+ // create parent config modules
+ ConfigurationModule parentConfigModule1 = createConfigurationModule("FOO", parentFooProperties, parentFooAttributes);
+ ConfigurationModule parentConfigModule2 = createConfigurationModule("BAR", parentBarProperties);
+ Collection<ConfigurationModule> parentModules = new ArrayList<ConfigurationModule>();
+ parentModules.add(parentConfigModule1);
+ parentModules.add(parentConfigModule2);
+
+ // create service modules
+ ServiceModule child = createServiceModule(info, childModules);
+ ServiceModule parent = createServiceModule(parentInfo, parentModules);
+
+ // resolve child with parent
+ resolveService(child, parent);
+
+ // assertions
+ Map<String, Map<String, Map<String, String>>> childTypeAttributes = child.getModuleInfo().getConfigTypeAttributes();
+ Map<String, Map<String, Map<String, String>>> parentTypeAttributes = parent.getModuleInfo().getConfigTypeAttributes();
+ assertTrue(childTypeAttributes.containsKey("FOO"));
+ Map<String, Map<String, String>> mergedChildFooAttributes = childTypeAttributes.get("FOO");
+ assertTrue(mergedChildFooAttributes.containsKey(ConfigurationInfo.Supports.KEYWORD));
+ // inherited value
+ assertEquals("true", mergedChildFooAttributes.get(ConfigurationInfo.Supports.KEYWORD).
+ get(ConfigurationInfo.Supports.valueOf("FINAL").getPropertyName()));
+ // overridden value
+ assertEquals("false", mergedChildFooAttributes.get(ConfigurationInfo.Supports.KEYWORD).
+ get(ConfigurationInfo.Supports.valueOf("ADDING_FORBIDDEN").getPropertyName()));
+
+ assertEquals(2, childTypeAttributes.size());
+
+ assertEquals(2, parentTypeAttributes.size());
+ assertAttributes(parentTypeAttributes.get("FOO"), parentFooAttributes);
+ assertAttributes(parentTypeAttributes.get("BAR"), Collections.<String, String>emptyMap());
+ }
+
+ @Test
+ public void testResolve_Configuration__ExcludedTypes() throws Exception {
+ ServiceInfo info = new ServiceInfo();
+ info.setExcludedConfigTypes(Collections.singleton("BAR"));
+
+ //FOO
+ Collection<PropertyInfo> fooProperties = new ArrayList<PropertyInfo>();
+ PropertyInfo prop1 = new PropertyInfo();
+ prop1.setName("name1");
+ prop1.setValue("val1");
+ fooProperties.add(prop1);
+ PropertyInfo prop2 = new PropertyInfo();
+ prop2.setName("name2");
+ prop2.setValue("val2");
+ fooProperties.add(prop2);
+
+ //BAR
+ Collection<PropertyInfo> barProperties = new ArrayList<PropertyInfo>();
+ PropertyInfo prop3 = new PropertyInfo();
+ prop3.setName("name1");
+ prop3.setValue("val3");
+ barProperties.add(prop3);
+
+ //OTHER
+ Collection<PropertyInfo> otherProperties = new ArrayList<PropertyInfo>();
+ PropertyInfo prop4 = new PropertyInfo();
+ prop4.setName("name1");
+ prop4.setValue("val4");
+ otherProperties.add(prop4);
+
+ ConfigurationModule configModule1 = createConfigurationModule("FOO", fooProperties);
+ ConfigurationModule configModule2 = createConfigurationModule("BAR", barProperties);
+ ConfigurationModule configModule3 = createConfigurationModule("OTHER", otherProperties);
+ Collection<ConfigurationModule> configModules = new ArrayList<ConfigurationModule>();
+ configModules.add(configModule1);
+ configModules.add(configModule2);
+ configModules.add(configModule3);
+
+ ServiceModule service = createServiceModule(info, configModules);
+
+ List<PropertyInfo> properties = service.getModuleInfo().getProperties();
+ assertEquals(3, properties.size());
+
+ Map<String, Map<String, Map<String, String>>> attributes = service.getModuleInfo().getConfigTypeAttributes();
+ assertEquals(2, attributes.size());
+ assertTrue(attributes.containsKey("FOO"));
+ assertTrue(attributes.containsKey("OTHER"));
+ }
+
+ @Test
+ public void testResolve_Configuration__ExcludedTypes__ParentType() throws Exception {
+ // child
+ ServiceInfo info = new ServiceInfo();
+ info.setExcludedConfigTypes(Collections.singleton("BAR"));
+
+ //FOO
+ Collection<PropertyInfo> fooProperties = new ArrayList<PropertyInfo>();
+ PropertyInfo prop1 = new PropertyInfo();
+ prop1.setName("name1");
+ prop1.setValue("val1");
+ fooProperties.add(prop1);
+ PropertyInfo prop2 = new PropertyInfo();
+ prop2.setName("name2");
+ prop2.setValue("val2");
+ fooProperties.add(prop2);
+
+ ConfigurationModule childConfigModule = createConfigurationModule("FOO", fooProperties);
+ Collection<ConfigurationModule> childConfigModules = new ArrayList<ConfigurationModule>();
+ childConfigModules.add(childConfigModule);
+
+ // parent
+ ServiceInfo parentInfo = new ServiceInfo();
+
+ //BAR
+ Collection<PropertyInfo> barProperties = new ArrayList<PropertyInfo>();
+ PropertyInfo prop3 = new PropertyInfo();
+ prop3.setName("name1");
+ prop3.setValue("val3");
+ barProperties.add(prop3);
+
+ ConfigurationModule parentConfigModule = createConfigurationModule("BAR", barProperties);
+ Collection<ConfigurationModule> parentConfigModules = new ArrayList<ConfigurationModule>();
+ parentConfigModules.add(parentConfigModule);
+
+ // create service modules
+ ServiceModule service = createServiceModule(info, childConfigModules);
+ ServiceModule parentService = createServiceModule(parentInfo, parentConfigModules);
+ // resolve child with parent
+ resolveService(service, parentService);
+ // assertions
+ List<PropertyInfo> properties = service.getModuleInfo().getProperties();
+ assertEquals(2, properties.size());
+
+ Map<String, Map<String, Map<String, String>>> attributes = service.getModuleInfo().getConfigTypeAttributes();
+ assertEquals(1, attributes.size());
+ assertTrue(attributes.containsKey("FOO"));
+
+ Map<String, Map<String, Map<String, String>>> parentAttributes = parentService.getModuleInfo().getConfigTypeAttributes();
+ assertEquals(1, parentAttributes.size());
+ assertTrue(parentAttributes.containsKey("BAR"));
+ }
+
+ @Test
+ public void testServiceCheckRegistered() throws Exception {
+ ServiceInfo info = new ServiceInfo();
+ info.setName("service1");
+ info.setCommandScript(createNiceMock(CommandScriptDefinition.class));
+
+ StackContext context = createStackContext(info.getName(), true);
+ ServiceModule service = createServiceModule(info, Collections.<ConfigurationModule>emptySet(), context);
+ service.finalizeModule();
+
+ verify(context);
+ }
+
+ @Test
+ public void testServiceCheckNotRegisteredForDeletedService() throws Exception {
+ ServiceInfo info = new ServiceInfo();
+ info.setName("service1");
+ info.setCommandScript(createNiceMock(CommandScriptDefinition.class));
+ info.setDeleted(true);
+
+ StackContext context = createStackContext(info.getName(), false);
+ ServiceModule service = createServiceModule(info, Collections.<ConfigurationModule>emptySet(), context);
+ service.finalizeModule();
+
+ verify(context);
+ }
+
+ private ServiceModule createServiceModule(ServiceInfo serviceInfo) {
+ String configType = "type1";
+
+ if (serviceInfo.getName() == null) {
+ serviceInfo.setName("service1");
+ }
+
+ StackContext context = createStackContext(serviceInfo.getName(), true);
+ // no config props
+ ConfigurationInfo configInfo = createConfigurationInfo(Collections.<PropertyInfo>emptyList(),
+ Collections.<String, String>emptyMap());
+
+ ConfigurationModule module = createConfigurationModule(configType, configInfo);
+ ConfigurationDirectory configDirectory = createConfigurationDirectory(Collections.singletonList(module));
+ ServiceDirectory serviceDirectory = createServiceDirectory(serviceInfo.getConfigDir(), configDirectory);
+
+ return createServiceModule(context, serviceInfo, serviceDirectory);
+ }
+
+ private ServiceModule createServiceModule(ServiceInfo serviceInfo,
+ Collection<ConfigurationModule> configurations,
+ StackContext context) {
+
+ if (serviceInfo.getName() == null) {
+ serviceInfo.setName("service1");
+ }
+
+ ConfigurationDirectory configDirectory = createConfigurationDirectory(configurations);
+ ServiceDirectory serviceDirectory = createServiceDirectory(serviceInfo.getConfigDir(), configDirectory);
+
+ return createServiceModule(context, serviceInfo, serviceDirectory);
+ }
+
+ private ServiceModule createServiceModule(ServiceInfo serviceInfo, Collection<ConfigurationModule> configurations) {
+ String serviceName = serviceInfo.getName();
+
+ if (serviceInfo.getName() == null) {
+ serviceInfo.setName("service1");
+ }
+
+ return createServiceModule(serviceInfo, configurations, createStackContext(serviceName, true));
+ }
+
+ private ServiceModule createServiceModule(StackContext context, ServiceInfo serviceInfo,
+ ServiceDirectory serviceDirectory) {
+
+ return new ServiceModule(context, serviceInfo, serviceDirectory);
+ }
+
+ private ServiceDirectory createServiceDirectory(String dir, ConfigurationDirectory configDir) {
+
+ ServiceDirectory serviceDirectory = createNiceMock(ServiceDirectory.class);
+
+ expect(serviceDirectory.getConfigurationDirectory(dir)).andReturn(configDir).anyTimes();
+ expect(serviceDirectory.getMetricsFile()).andReturn(new File("testMetricsFile")).anyTimes();
+ expect(serviceDirectory.getAlertsFile()).andReturn(new File("testAlertsFile")).anyTimes();
+ expect(serviceDirectory.getPackageDir()).andReturn("packageDir").anyTimes();
+ replay(serviceDirectory);
+
+ return serviceDirectory;
+ }
+
+ private ConfigurationDirectory createConfigurationDirectory(Collection<ConfigurationModule> modules) {
+ ConfigurationDirectory configDir = createNiceMock(ConfigurationDirectory.class);
+
+ expect(configDir.getConfigurationModules()).andReturn(modules).anyTimes();
+ replay(configDir);
+
+ return configDir;
+ }
+
+ private ConfigurationModule createConfigurationModule(String configType, ConfigurationInfo info) {
+ return new ConfigurationModule(configType, info);
+ }
+
+ private ConfigurationModule createConfigurationModule(String configType, Collection<PropertyInfo> properties) {
+ ConfigurationInfo info = new ConfigurationInfo(properties, Collections.<String, String>emptyMap());
+ return new ConfigurationModule(configType, info);
+ }
+
+ private ConfigurationModule createConfigurationModule(String configType,
+ Collection<PropertyInfo> properties,
+ Map<String, String> attributes) {
+
+ ConfigurationInfo info = new ConfigurationInfo(properties, attributes);
+ return new ConfigurationModule(configType, info);
+ }
+
+ private ConfigurationInfo createConfigurationInfo(Collection<PropertyInfo> properties,
+ Map<String, String> attributes) {
+
+ return new ConfigurationInfo(properties, attributes);
+ }
+
+ private StackContext createStackContext(String serviceName, boolean expectServiceRegistration) {
+ StackContext context = createStrictMock(StackContext.class);
+
+ if (expectServiceRegistration) {
+ context.registerServiceCheck(serviceName);
+ }
+ replay(context);
+
+ return context;
+ }
+
+ private ServiceModule resolveService(ServiceInfo info, ServiceInfo parentInfo) throws AmbariException {
+ ServiceModule service = createServiceModule(info);
+ ServiceModule parentService = createServiceModule(parentInfo);
+
+ resolveService(service, parentService);
+ return service;
+ }
+
+ private void resolveService(ServiceModule service, ServiceModule parent) throws AmbariException {
+ service.resolve(parent, Collections.<String, StackModule>emptyMap());
+ // during runtime this would be called by the Stack module when it's resolve completed
+ service.finalizeModule();
+ parent.finalizeModule();
+ }
+
+ private void assertAttributes(Map<String, Map<String, String>> mergedAttributes, Map<String, String> specifiedAttributes) {
+ assertEquals(1, mergedAttributes.size()); // only supports
+ Map<String, String> supportsAttributes = mergedAttributes.get(ConfigurationInfo.Supports.KEYWORD);
+ assertEquals(ConfigurationInfo.Supports.values().length, supportsAttributes.size());
+ for (Map.Entry<String, String> attribute : supportsAttributes.entrySet()) {
+ String attributeName = attribute.getKey();
+ String attributeValue = attribute.getValue();
+
+ //need to call toUpper() because propertyName is name().toLowerCase()
+ ConfigurationInfo.Supports s = ConfigurationInfo.Supports.valueOf(attributeName.toUpperCase());
+ String specifiedVal = specifiedAttributes.get(s.getXmlAttributeName());
+ if (specifiedVal != null) {
+ assertEquals(specifiedVal, attributeValue);
+ } else {
+ assertEquals(s.getDefaultValue(), attributeValue);
+ }
+ }
+ }
+
+ 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); }
+}