| /** |
| * 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.state; |
| |
| import com.google.inject.Binder; |
| import com.google.inject.Guice; |
| import com.google.inject.Injector; |
| import com.google.inject.Module; |
| import com.google.inject.persist.PersistService; |
| import com.google.inject.util.Modules; |
| import org.apache.ambari.server.api.services.AmbariMetaInfo; |
| import org.apache.ambari.server.orm.GuiceJpaInitializer; |
| import org.apache.ambari.server.orm.InMemoryDefaultTestModule; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import static org.easymock.EasyMock.anyString; |
| import static org.easymock.EasyMock.expect; |
| import static org.easymock.EasyMock.replay; |
| import static org.easymock.EasyMock.createNiceMock; |
| import static org.junit.Assert.assertEquals; |
| import static org.apache.ambari.server.state.ConfigMergeHelper.ThreeWayValue; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| /** |
| * Tests the {@link ConfigMergeHelper} class |
| */ |
| public class ConfigMergeHelperTest { |
| |
| private static final StackId currentStackId = new StackId("HDP-2.1.1"); |
| private static final StackId newStackId = new StackId("HPD-2.2.0"); |
| |
| private Injector injector; |
| private Clusters clustersMock; |
| private AmbariMetaInfo ambariMetaInfoMock; |
| |
| @Before |
| public void before() throws Exception { |
| clustersMock = createNiceMock(Clusters.class); |
| ambariMetaInfoMock = createNiceMock(AmbariMetaInfo.class); |
| |
| final InMemoryDefaultTestModule injectorModule = new InMemoryDefaultTestModule() { |
| @Override |
| protected void configure() { |
| super.configure(); |
| } |
| }; |
| |
| MockModule mockModule = new MockModule(); |
| // create an injector which will inject the mocks |
| injector = Guice.createInjector(Modules.override(injectorModule).with(mockModule)); |
| injector.getInstance(GuiceJpaInitializer.class); |
| } |
| |
| @After |
| public void teardown() { |
| injector.getInstance(PersistService.class).stop(); |
| } |
| |
| @Test |
| public void testGetConflicts() throws Exception { |
| Cluster clusterMock = createNiceMock(Cluster.class); |
| |
| expect(clustersMock.getCluster(anyString())).andReturn(clusterMock); |
| |
| expect(clusterMock.getCurrentStackVersion()).andReturn(currentStackId); |
| expect(clusterMock.getServices()).andReturn(new HashMap<String, Service>() {{ |
| put("HDFS", createNiceMock(Service.class)); |
| put("ZK", createNiceMock(Service.class)); |
| }}); |
| |
| |
| Set<PropertyInfo> currentHDFSProperties = new HashSet<PropertyInfo>() {{ |
| add(createPropertyInfo("hdfs-env.xml", "equal.key", "equal-value")); |
| }}; |
| |
| Set<PropertyInfo> currentZKProperties = new HashSet<PropertyInfo>() {{ |
| add(createPropertyInfo("zk-env.xml", "different.key", "different-value-1")); |
| }}; |
| |
| Set<PropertyInfo> currentStackProperties = new HashSet<PropertyInfo>() {{ |
| add(createPropertyInfo("hadoop-env.xml", "equal.key", "modified.value")); |
| }}; |
| |
| expect(ambariMetaInfoMock.getServiceProperties(currentStackId.getStackName(), |
| currentStackId.getStackVersion(), "HDFS")).andReturn(currentHDFSProperties); |
| expect(ambariMetaInfoMock.getServiceProperties(currentStackId.getStackName(), |
| currentStackId.getStackVersion(), "ZK")).andReturn(currentZKProperties); |
| expect(ambariMetaInfoMock.getStackProperties(currentStackId.getStackName(), |
| currentStackId.getStackVersion())).andReturn(currentStackProperties); |
| |
| Set<PropertyInfo> newHDFSProperties = new HashSet<PropertyInfo>() {{ |
| add(createPropertyInfo("hdfs-env.xml", "equal.key", "equal-value")); |
| add(createPropertyInfo("new-hdfs-config.xml", "equal.key", "equal-value")); |
| }}; |
| |
| Set<PropertyInfo> newZKProperties = new HashSet<PropertyInfo>() {{ |
| add(createPropertyInfo("zk-env.xml", "equal.key", "different-value-2")); |
| add(createPropertyInfo("zk-env.xml", "new.key", "new-value-2")); |
| }}; |
| |
| Set<PropertyInfo> newStackProperties = new HashSet<PropertyInfo>() {{ |
| add(createPropertyInfo("hadoop-env.xml", "equal.key", "another.value")); |
| }}; |
| |
| expect(ambariMetaInfoMock.getServiceProperties(newStackId.getStackName(), |
| newStackId.getStackVersion(), "HDFS")).andReturn(newHDFSProperties); |
| expect(ambariMetaInfoMock.getServiceProperties(newStackId.getStackName(), |
| newStackId.getStackVersion(), "ZK")).andReturn(newZKProperties); |
| expect(ambariMetaInfoMock.getStackProperties(newStackId.getStackName(), |
| newStackId.getStackVersion())).andReturn(newStackProperties); |
| |
| // desired config of hdfs-env.xml |
| Map<String, String> desiredHdfsEnvProperties = new HashMap<String, String>() {{ |
| |
| }}; |
| expect(clusterMock.getDesiredConfigByType("hdfs-env.xml")).andReturn( |
| createConfigMock(desiredHdfsEnvProperties) |
| ); |
| |
| // desired config of zk-env.xml |
| Map<String, String> desiredZkEnvProperties = new HashMap<String, String>() {{ |
| |
| }}; |
| expect(clusterMock.getDesiredConfigByType("hdfs-env.xml")).andReturn( |
| createConfigMock(desiredZkEnvProperties) |
| ); |
| |
| // desired config of hadoop-env.xml |
| Map<String, String> desiredHadoopEnvProperties = new HashMap<String, String>() {{ |
| |
| }}; |
| expect(clusterMock.getDesiredConfigByType("hadoop-env.xml")).andReturn( |
| createConfigMock(desiredHadoopEnvProperties) |
| ); |
| |
| replay(clusterMock, clustersMock, ambariMetaInfoMock); |
| |
| ConfigMergeHelper configMergeHelper = injector.getInstance(ConfigMergeHelper.class); |
| |
| Map<String, Map<String, ThreeWayValue>> conflicts = configMergeHelper.getConflicts( |
| "clustername", newStackId); |
| |
| assertNotNull(conflicts); |
| assertEquals(2, conflicts.size()); |
| for (String key : conflicts.keySet()) { |
| if (key.equals("hdfs-env")) { |
| Map<String, ThreeWayValue> stringThreeWayValueMap = conflicts.get(key); |
| assertEquals(1, stringThreeWayValueMap.size()); |
| assertEquals("equal-value", stringThreeWayValueMap.get("equal.key").oldStackValue); |
| assertEquals("equal-value", stringThreeWayValueMap.get("equal.key").newStackValue); |
| assertEquals("", stringThreeWayValueMap.get("equal.key").savedValue); |
| } else if (key.equals("hadoop-env")) { |
| Map<String, ThreeWayValue> stringThreeWayValueMap = conflicts.get(key); |
| assertEquals(1, stringThreeWayValueMap.size()); |
| assertEquals("modified.value", stringThreeWayValueMap.get("equal.key").oldStackValue); |
| assertEquals("another.value", stringThreeWayValueMap.get("equal.key").newStackValue); |
| assertEquals("", stringThreeWayValueMap.get("equal.key").savedValue); |
| } else { |
| fail("Unexpected key"); |
| } |
| } |
| assertEquals(2, conflicts.size()); |
| } |
| |
| private PropertyInfo createPropertyInfo(String fileName, String name, String value) { |
| PropertyInfo result = new PropertyInfo(); |
| result.setFilename(fileName); |
| result.setName(name); |
| result.setValue(value); |
| return result; |
| } |
| |
| /** |
| * Generates config that returns properties |
| * @param properties properties that should be returned by config mock |
| * @return mock |
| */ |
| private Config createConfigMock(Map<String, String> properties) { |
| Config result = createNiceMock(Config.class); |
| expect(result.getProperties()).andReturn(properties); |
| return result; |
| } |
| |
| @Test |
| public void testNormalizeValue() throws Exception{ |
| // If template not defined |
| String normalizedValue = ConfigMergeHelper.normalizeValue(null, "2048m"); |
| assertEquals("2048m", normalizedValue); |
| |
| // Template does not define heap |
| normalizedValue = ConfigMergeHelper.normalizeValue("3k", "2048"); |
| assertEquals("2048", normalizedValue); |
| |
| // Template - megabytes |
| normalizedValue = ConfigMergeHelper.normalizeValue("1024m", "2048"); |
| assertEquals("2048m", normalizedValue); |
| |
| normalizedValue = ConfigMergeHelper.normalizeValue("1024M", "2048"); |
| assertEquals("2048M", normalizedValue); |
| |
| // Template - gigabytes |
| normalizedValue = ConfigMergeHelper.normalizeValue("4g", "2"); |
| assertEquals("2g", normalizedValue); |
| |
| normalizedValue = ConfigMergeHelper.normalizeValue("4G", "2"); |
| assertEquals("2G", normalizedValue); |
| } |
| |
| |
| |
| private class MockModule implements Module { |
| |
| @Override |
| public void configure(Binder binder) { |
| binder.bind(Clusters.class).toInstance(clustersMock); |
| binder.bind(AmbariMetaInfo.class).toInstance(ambariMetaInfoMock); |
| } |
| } |
| } |