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.serveraction.upgrades;
  
  import static org.easymock.EasyMock.anyObject;
  import static org.easymock.EasyMock.anyString;
  import static org.easymock.EasyMock.capture;
  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 java.lang.reflect.Field;
  import java.util.HashMap;
  import java.util.Map;
  import java.util.TreeMap;
  
  import org.apache.ambari.server.actionmanager.ExecutionCommandWrapper;
  import org.apache.ambari.server.actionmanager.HostRoleCommand;
  import org.apache.ambari.server.agent.ExecutionCommand;
  import org.apache.ambari.server.api.services.AmbariMetaInfo;
  import org.apache.ambari.server.orm.dao.ArtifactDAO;
  import org.apache.ambari.server.orm.entities.ArtifactEntity;
  import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
  import org.apache.ambari.server.orm.entities.UpgradeEntity;
  import org.apache.ambari.server.stack.upgrade.Direction;
  import org.apache.ambari.server.stack.upgrade.orchestrate.UpgradeContext;
  import org.apache.ambari.server.stack.upgrade.orchestrate.UpgradeContextFactory;
  import org.apache.ambari.server.state.Cluster;
  import org.apache.ambari.server.state.Clusters;
  import org.apache.ambari.server.state.StackId;
  import org.apache.ambari.server.state.kerberos.KerberosDescriptor;
  import org.apache.ambari.server.state.kerberos.KerberosDescriptorFactory;
  import org.apache.ambari.server.state.kerberos.KerberosDescriptorUpdateHelper;
  import org.easymock.Capture;
  import org.easymock.EasyMock;
  import org.junit.Before;
  import org.junit.Test;
  import org.junit.runner.RunWith;
  import org.powermock.api.mockito.PowerMockito;
  import org.powermock.core.classloader.annotations.PrepareForTest;
  import org.powermock.modules.junit4.PowerMockRunner;
  
  /**
   * Tests OozieConfigCalculation logic
   */
  @RunWith(PowerMockRunner.class)
  @PrepareForTest(KerberosDescriptorUpdateHelper.class)
  public class UpgradeUserKerberosDescriptorTest {
    private Clusters clusters;
    private Cluster cluster;
    private UpgradeEntity upgrade;
    private UpgradeContext upgradeContext;
    private AmbariMetaInfo ambariMetaInfo;
    private KerberosDescriptorFactory kerberosDescriptorFactory;
    private ArtifactDAO artifactDAO;
    private UpgradeContextFactory upgradeContextFactory;
  
    private TreeMap<String, Field> fields = new TreeMap<>();
    private StackId HDP_24 = new StackId("HDP", "2.4");
  
    @Before
    public void setup() throws Exception {
      clusters = EasyMock.createMock(Clusters.class);
      cluster = EasyMock.createMock(Cluster.class);
      upgrade = EasyMock.createNiceMock(UpgradeEntity.class);
      kerberosDescriptorFactory = EasyMock.createNiceMock(KerberosDescriptorFactory.class);
      ambariMetaInfo = EasyMock.createMock(AmbariMetaInfo.class);
      artifactDAO = EasyMock.createNiceMock(ArtifactDAO.class);
      upgradeContextFactory = EasyMock.createNiceMock(UpgradeContextFactory.class);
      upgradeContext = EasyMock.createNiceMock(UpgradeContext.class);
  
      expect(clusters.getCluster((String) anyObject())).andReturn(cluster).anyTimes();
      expect(cluster.getClusterId()).andReturn(1l).atLeastOnce();
      expect(cluster.getCurrentStackVersion()).andReturn(HDP_24).atLeastOnce();
      expect(cluster.getUpgradeInProgress()).andReturn(upgrade).atLeastOnce();
      expect(upgradeContextFactory.create(cluster, upgrade)).andReturn(upgradeContext).atLeastOnce();
  
      replay(clusters, cluster, upgradeContextFactory, upgrade);
  
      prepareFields();
  
    }
  
    @Test
    public void testUpgrade() throws Exception {
      StackId stackId = new StackId("HDP", "2.5");
      RepositoryVersionEntity repositoryVersion = EasyMock.createNiceMock(RepositoryVersionEntity.class);
      expect(repositoryVersion.getStackId()).andReturn(stackId).atLeastOnce();
  
      expect(upgradeContext.getDirection()).andReturn(Direction.UPGRADE).atLeastOnce();
      expect(upgradeContext.getRepositoryVersion()).andReturn(repositoryVersion).atLeastOnce();
      replay(repositoryVersion, upgradeContext);
  
      Map<String, String> commandParams = new HashMap<>();
      commandParams.put("clusterName", "c1");
  
      ExecutionCommand executionCommand = new ExecutionCommand();
      executionCommand.setCommandParams(commandParams);
      executionCommand.setClusterName("c1");
  
      HostRoleCommand hrc = EasyMock.createMock(HostRoleCommand.class);
      expect(hrc.getRequestId()).andReturn(1L).anyTimes();
      expect(hrc.getStageId()).andReturn(2L).anyTimes();
      expect(hrc.getExecutionCommandWrapper()).andReturn(new ExecutionCommandWrapper(executionCommand)).anyTimes();
      replay(hrc);
  
      UpgradeUserKerberosDescriptor action = new UpgradeUserKerberosDescriptor();
      injectFields(action);
  
      action.setExecutionCommand(executionCommand);
      action.setHostRoleCommand(hrc);
  
      ArtifactEntity entity = EasyMock.createNiceMock(ArtifactEntity.class);
      expect(entity.getArtifactData()).andReturn(null).anyTimes();
      expect(entity.getForeignKeys()).andReturn(null).anyTimes();
      expect(artifactDAO.findByNameAndForeignKeys(anyString(), (TreeMap<String, String>) anyObject())).andReturn(entity).atLeastOnce();
  
      KerberosDescriptor userDescriptor = EasyMock.createMock(KerberosDescriptor.class);
      KerberosDescriptor newDescriptor = EasyMock.createMock(KerberosDescriptor.class);
      KerberosDescriptor previousDescriptor = EasyMock.createMock(KerberosDescriptor.class);
      KerberosDescriptor updatedKerberosDescriptor = EasyMock.createMock(KerberosDescriptor.class);
  
      PowerMockito.mockStatic(KerberosDescriptorUpdateHelper.class);
      PowerMockito.when(KerberosDescriptorUpdateHelper.updateUserKerberosDescriptor(previousDescriptor, newDescriptor, userDescriptor)).thenAnswer(invocation -> updatedKerberosDescriptor);
      expect(kerberosDescriptorFactory.createInstance((Map)null)).andReturn(userDescriptor).atLeastOnce();
      expect(ambariMetaInfo.getKerberosDescriptor("HDP","2.5", false)).andReturn(newDescriptor).atLeastOnce();
      expect(ambariMetaInfo.getKerberosDescriptor("HDP","2.4",false)).andReturn(previousDescriptor).atLeastOnce();
  
  
      expect(updatedKerberosDescriptor.toMap()).andReturn(null).once();
  
  
      expect(artifactDAO.merge(entity)).andReturn(entity).once();
      Capture<ArtifactEntity> createCapture = Capture.newInstance();
      artifactDAO.create(capture(createCapture));
      EasyMock.expectLastCall().once();
  
      replay(artifactDAO, entity, ambariMetaInfo, kerberosDescriptorFactory, updatedKerberosDescriptor);
  
      action.execute(null);
  
      verify(artifactDAO, updatedKerberosDescriptor);
      assertEquals(createCapture.getValue().getArtifactName(), "kerberos_descriptor_backup");
    }
  
    @Test
    public void testDowngrade() throws Exception {
      StackId stackId = new StackId("HDP", "2.5");
      RepositoryVersionEntity repositoryVersion = EasyMock.createNiceMock(RepositoryVersionEntity.class);
      expect(repositoryVersion.getStackId()).andReturn(stackId).atLeastOnce();
  
      expect(upgradeContext.getDirection()).andReturn(Direction.DOWNGRADE).atLeastOnce();
      expect(upgradeContext.getRepositoryVersion()).andReturn(repositoryVersion).atLeastOnce();
      replay(repositoryVersion, upgradeContext);
  
      Map<String, String> commandParams = new HashMap<>();
      commandParams.put("clusterName", "c1");
  
      ExecutionCommand executionCommand = new ExecutionCommand();
      executionCommand.setCommandParams(commandParams);
      executionCommand.setClusterName("c1");
  
      HostRoleCommand hrc = EasyMock.createMock(HostRoleCommand.class);
      expect(hrc.getRequestId()).andReturn(1L).anyTimes();
      expect(hrc.getStageId()).andReturn(2L).anyTimes();
      expect(hrc.getExecutionCommandWrapper()).andReturn(new ExecutionCommandWrapper(executionCommand)).anyTimes();
      replay(hrc);
  
      UpgradeUserKerberosDescriptor action = new UpgradeUserKerberosDescriptor();
      injectFields(action);
  
      action.setExecutionCommand(executionCommand);
      action.setHostRoleCommand(hrc);
  
      ArtifactEntity entity = EasyMock.createNiceMock(ArtifactEntity.class);
      expect(entity.getArtifactData()).andReturn(null).anyTimes();
      expect(entity.getForeignKeys()).andReturn(null).anyTimes();
      expect(artifactDAO.findByNameAndForeignKeys(anyString(), (TreeMap<String, String>) anyObject())).andReturn(entity).atLeastOnce();
  
      KerberosDescriptor userDescriptor = EasyMock.createMock(KerberosDescriptor.class);
  
      expect(kerberosDescriptorFactory.createInstance((Map)null)).andReturn(userDescriptor).atLeastOnce();
  
      Capture<ArtifactEntity> createCapture = Capture.newInstance();
      artifactDAO.create(capture(createCapture));
      EasyMock.expectLastCall().once();
  
      artifactDAO.remove(entity);
      EasyMock.expectLastCall().atLeastOnce();
  
      replay(artifactDAO, entity, ambariMetaInfo, kerberosDescriptorFactory);
  
      action.execute(null);
  
      verify(artifactDAO);
      assertEquals(createCapture.getValue().getArtifactName(), "kerberos_descriptor");
    }
  
    private void prepareFields() throws NoSuchFieldException {
      String[] fieldsNames = { "artifactDAO", "m_clusters", "ambariMetaInfo",
          "kerberosDescriptorFactory", "m_upgradeContextFactory" };
  
      for (String fieldName : fieldsNames) {
        try {
          Field clustersField = UpgradeUserKerberosDescriptor.class.getDeclaredField(fieldName);
          clustersField.setAccessible(true);
          fields.put(fieldName, clustersField);
        } catch( NoSuchFieldException noSuchFieldException ){
          Field clustersField = UpgradeUserKerberosDescriptor.class.getSuperclass().getDeclaredField(fieldName);
          clustersField.setAccessible(true);
          fields.put(fieldName, clustersField);
        }
      }
    }
    private void injectFields(UpgradeUserKerberosDescriptor action) throws IllegalAccessException {
      fields.get("artifactDAO").set(action, artifactDAO);
      fields.get("m_clusters").set(action, clusters);
      fields.get("ambariMetaInfo").set(action, ambariMetaInfo);
      fields.get("kerberosDescriptorFactory").set(action, kerberosDescriptorFactory);
      fields.get("m_upgradeContextFactory").set(action, upgradeContextFactory);
    }
  }
  