content: /*
   * 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 java.util.Arrays.asList;
  import static java.util.Collections.singletonList;
  import static org.easymock.EasyMock.expect;
  import static org.junit.Assert.assertTrue;
  import static org.powermock.api.easymock.PowerMock.createNiceMock;
  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.util.Collection;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Map;
  import java.util.Set;
  
  import org.apache.ambari.server.state.ComponentInfo;
  import org.apache.ambari.server.state.ServiceInfo;
  import org.junit.After;
  import org.junit.Before;
  import org.junit.Test;
  
  /**
   * Unit tests for ClusterTopologyImpl.
   */
  @SuppressWarnings("unchecked")
  public class ClusterTopologyImplTest {
  
    private static final String CLUSTER_NAME = "cluster_name";
    private static final long CLUSTER_ID = 1L;
    private static final String predicate = "Hosts/host_name=foo";
    private final Blueprint blueprint = createNiceMock(Blueprint.class);
    private final HostGroup group1 = createNiceMock(HostGroup.class);
    private final HostGroup group2 = createNiceMock(HostGroup.class);
    private final HostGroup group3 = createNiceMock(HostGroup.class);
    private final HostGroup group4 = createNiceMock(HostGroup.class);
    private final Map<String, HostGroupInfo> hostGroupInfoMap = new HashMap<>();
    private final Map<String, HostGroup> hostGroupMap = new HashMap<>();
  
    private Configuration configuration;
    private Configuration bpconfiguration;
  
    @Before
    public void setUp() throws Exception {
  
      configuration = new Configuration(new HashMap<>(),
        new HashMap<>());
      bpconfiguration = new Configuration(new HashMap<>(),
        new HashMap<>());
  
      HostGroupInfo group1Info = new HostGroupInfo("group1");
      HostGroupInfo group2Info = new HostGroupInfo("group2");
      HostGroupInfo group3Info = new HostGroupInfo("group3");
      HostGroupInfo group4Info = new HostGroupInfo("group4");
      hostGroupInfoMap.put("group1", group1Info);
      hostGroupInfoMap.put("group2", group2Info);
      hostGroupInfoMap.put("group3", group3Info);
      hostGroupInfoMap.put("group4", group4Info);
  
      group1Info.setConfiguration(configuration);
      Collection<String> group1Hosts = new HashSet<>();
      group1Hosts.add("host1");
      group1Hosts.add("host2");
      group1Info.addHosts(group1Hosts);
  
      group2Info.setConfiguration(configuration);
      Collection<String> group2Hosts = new HashSet<>();
      group2Hosts.add("host3");
      group2Info.addHosts(group2Hosts);
      Collection<String> group4Hosts = new HashSet<>();
      group4Hosts.add("host4");
      group4Hosts.add("host5");
      group4Info.addHosts(group4Hosts);
  
      group3Info.setConfiguration(configuration);
      group3Info.setRequestedCount(5);
  
      group4Info.setConfiguration(configuration);
      group4Info.setRequestedCount(5);
      group4Info.setPredicate(predicate);
  
      expect(blueprint.getConfiguration()).andReturn(bpconfiguration).anyTimes();
  
      hostGroupMap.put("group1", group1);
      hostGroupMap.put("group2", group2);
      hostGroupMap.put("group3", group3);
      hostGroupMap.put("group4", group4);
  
      Set<Component> group1Components = new HashSet<>();
      group1Components.add(new Component("component1"));
      group1Components.add(new Component("component2"));
  
      Set<String> group1ComponentNames = new HashSet<>();
      group1ComponentNames.add("component1");
      group1ComponentNames.add("component2");
  
      Set<Component> group2Components = new HashSet<>();
      group2Components.add(new Component("component3"));
      Set<Component> group3Components = new HashSet<>();
      group3Components.add(new Component("component4"));
      Set<Component> group4Components = new HashSet<>();
      group4Components.add(new Component("component5"));
  
      expect(blueprint.getHostGroups()).andReturn(hostGroupMap).anyTimes();
      expect(blueprint.getHostGroup("group1")).andReturn(group1).anyTimes();
      expect(blueprint.getHostGroup("group2")).andReturn(group2).anyTimes();
      expect(blueprint.getHostGroup("group3")).andReturn(group3).anyTimes();
      expect(blueprint.getHostGroup("group4")).andReturn(group4).anyTimes();
  
      expect(group1.getConfiguration()).andReturn(configuration).anyTimes();
      expect(group2.getConfiguration()).andReturn(configuration).anyTimes();
      expect(group3.getConfiguration()).andReturn(configuration).anyTimes();
      expect(group4.getConfiguration()).andReturn(configuration).anyTimes();
  
      expect(group1.getComponents()).andReturn(group1Components).anyTimes();
      expect(group2.getComponents()).andReturn(group2Components).anyTimes();
      expect(group3.getComponents()).andReturn(group3Components).anyTimes();
      expect(group4.getComponents()).andReturn(group4Components).anyTimes();
  
      expect(group1.getComponentNames()).andReturn(group1ComponentNames).anyTimes();
      expect(group2.getComponentNames()).andReturn(singletonList("component3")).anyTimes();
      expect(group3.getComponentNames()).andReturn(singletonList("component4")).anyTimes();
      expect(group4.getComponentNames()).andReturn(singletonList("NAMENODE")).anyTimes();
    }
  
    @After
    public void tearDown() {
      verify(blueprint, group1, group2, group3, group4);
      reset(blueprint, group1, group2, group3, group4);
  
      hostGroupInfoMap.clear();
      hostGroupMap.clear();
    }
  
    private void replayAll() {
      replay(blueprint, group1, group2, group3, group4);
    }
  
  
  
    @Test(expected = InvalidTopologyException.class)
    public void testCreate_duplicateHosts() throws Exception {
      // add a duplicate host
      hostGroupInfoMap.get("group2").addHost("host1");
  
      TestTopologyRequest request = new TestTopologyRequest(TopologyRequest.Type.PROVISION);
  
      replayAll();
      // should throw exception due to duplicate host
      new ClusterTopologyImpl(null, request);
    }
  
    @Test
    public void test_GetHostAssigmentForComponents() throws Exception {
      TestTopologyRequest request = new TestTopologyRequest(TopologyRequest.Type.PROVISION);
  
      replayAll();
  
      new ClusterTopologyImpl(null, request).getHostAssignmentsForComponent("component1");
    }
  
    @Test
    public void testDecidingIfComponentIsHadoopCompatible() throws Exception {
      expect(blueprint.getServiceInfos()).andReturn(asList(
        aHCFSWith(aComponent("ONEFS_CLIENT")),
        aServiceWith(aComponent("ZOOKEEPER_CLIENT")))
      ).anyTimes();
      replayAll();
      ClusterTopologyImpl topology = new ClusterTopologyImpl(null, new TestTopologyRequest(TopologyRequest.Type.PROVISION));
      assertTrue(topology.hasHadoopCompatibleService());
    }
  
    private ServiceInfo aHCFSWith(ComponentInfo... components) {
      ServiceInfo service = aServiceWith(components);
      service.setServiceType(ServiceInfo.HADOOP_COMPATIBLE_FS);
      return service;
    }
  
    private ServiceInfo aServiceWith(ComponentInfo... components) {
      ServiceInfo service = new ServiceInfo();
      service.getComponents().addAll(asList(components));
      return service;
    }
  
    private ComponentInfo aComponent(String name) {
      ComponentInfo component = new ComponentInfo();
      component.setName(name);
      return component;
    }
  
    private class TestTopologyRequest implements TopologyRequest {
      private Type type;
  
      public TestTopologyRequest(Type type) {
        this.type = type;
      }
  
      public String getClusterName() {
        return CLUSTER_NAME;
      }
  
      @Override
      public Long getClusterId() {
        return CLUSTER_ID;
      }
  
      @Override
      public Type getType() {
        return type;
      }
  
      @Override
      public Blueprint getBlueprint() {
        return blueprint;
      }
  
      @Override
      public Configuration getConfiguration() {
        return bpconfiguration;
      }
  
      @Override
      public Map<String, HostGroupInfo> getHostGroupInfo() {
        return hostGroupInfoMap;
      }
  
      @Override
      public String getDescription() {
        return "Test Request";
      }
    }
  }
  