/** * 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.falcon.regression.core.util; import org.apache.falcon.entity.v0.Entity; import org.apache.falcon.entity.v0.EntityType; import org.apache.falcon.entity.v0.Frequency; import org.apache.falcon.regression.core.helpers.ColoHelper; import org.apache.falcon.resource.InstancesResult; import org.apache.hadoop.security.authentication.client.AuthenticationException; import org.apache.log4j.Logger; import org.apache.oozie.client.CoordinatorAction; import org.testng.Assert; import java.io.IOException; import java.net.URISyntaxException; /** * Util functions related to native instance test. * In case of entity scheduled using native scheduler, we cannot use oozie coordinator to retrieve relevant information * This util retrieves instance related information using falcon APIs */ public final class NativeInstanceUtil { public static final int INSTANCES_CREATED_TIMEOUT = OSUtil.IS_WINDOWS ? 20 : 10; private static final Logger LOGGER = Logger.getLogger(NativeInstanceUtil.class); private NativeInstanceUtil() { throw new AssertionError("Instantiating utility class..."); } /** * Waits till instance of specific entity will be created during timeout. * Timeout is common for most of usual test cases. * Using status API to retrieve instance information. * * @param cluster ColoHelper - colo on which API to be executed * @param entity definition of entity which describes job * @param startTime start time of instance * @param endTime end time of instance */ public static void waitTillInstancesAreCreated(ColoHelper cluster, Entity entity, String startTime, String endTime) throws InterruptedException, IOException, AuthenticationException, URISyntaxException { waitTillInstancesAreCreated(cluster, entity, startTime, endTime, INSTANCES_CREATED_TIMEOUT); } /** * Waits till instances of specific job will be created during specific time. * Use this method directly in unusual test cases where timeouts are different from trivial. * In other cases use waitTillInstancesAreCreated(ColoHelper,Entity,String,String) * Using status API to retrieve instance information. * * @param cluster ColoHelper - colo on which API to be executed * @param entity definition of entity which describes job * @param startTime start time of instance * @param endTime end time of instance * @param totalMinutesToWait total time(in minutes) to wait for instance creation */ public static void waitTillInstancesAreCreated(ColoHelper cluster, Entity entity, String startTime, String endTime, int totalMinutesToWait) throws URISyntaxException, AuthenticationException, InterruptedException, IOException { String entityName = entity.getName(); EntityType type = entity.getEntityType(); String params = "?start=" + startTime; params += (endTime.isEmpty() ? "" : "&end=" + endTime); // totalSecondsToWait (totalMinutesToWait in seconds) int totalSecondsToWait = totalMinutesToWait * 60; //Incrementing sleepSeconds by 10 so that looping happens (totalMinutesToWait*60)/10 times //since TimeUtil.sleepSeconds is 10 for (int sleepSeconds = 0; sleepSeconds < totalSecondsToWait; sleepSeconds = sleepSeconds+10) { InstancesResult statusResult = cluster.getProcessHelper().getProcessInstanceStatus(entityName, params); if (statusResult.getInstances() != null) { return; } LOGGER.info(type + " " + entityName + " still doesn't have instance created"); TimeUtil.sleepSeconds(10); } Assert.fail("Instances not created"); } /** * Waits till given instance of process/feed reach expected state during specific time. * Using status API to retrieve instance information. * * @param cluster ColoHelper - colo on which API to be executed * @param entity definition of entity which describes job * @param instanceTime time of instance * @param expectedStatus expected status we are waiting for * @param frequency frequency of process/feed */ public static void waitTillInstanceReachState(ColoHelper cluster, Entity entity, String instanceTime, CoordinatorAction.Status expectedStatus, Frequency frequency) throws InterruptedException, IOException, AuthenticationException, URISyntaxException { int totalMinutesToWait = InstanceUtil.getMinutesToWait(entity.getEntityType(), expectedStatus); waitTillInstanceReachState(cluster, entity, instanceTime, expectedStatus, frequency, totalMinutesToWait); } /** * Waits till given instance of process/feed reach expected state during specific time. * Using status API to retrieve instance information. * * @param cluster ColoHelper - colo on which API to be executed * @param entity definition of entity which describes job * @param instanceTime time of instance * @param expectedStatus expected status we are waiting for * @param frequency frequency of process/feed * @param totalMinutesToWait total time(in minutes) to wait */ public static void waitTillInstanceReachState(ColoHelper cluster, Entity entity, String instanceTime, CoordinatorAction.Status expectedStatus, Frequency frequency, int totalMinutesToWait) throws URISyntaxException, AuthenticationException, InterruptedException, IOException { String entityName = entity.getName(); EntityType type = entity.getEntityType(); String endTime=getNextInstanceTime(instanceTime, frequency); String params = "?start=" + instanceTime + "&end=" + endTime; int totalSleepTime = totalMinutesToWait * 60; int sleepTime = 10; for (int i = 0; i < totalSleepTime; i = i+sleepTime) { InstancesResult statusResult = cluster.getProcessHelper().getProcessInstanceStatus(entityName, params); if (statusResult.getInstances() != null) { if ((statusResult.getInstances()[0].getStatus().name()).equals(expectedStatus.name())) { return; } } LOGGER.info(type + " " + entityName + " still doesn't have expected status"); TimeUtil.sleepSeconds(sleepTime); } Assert.fail("expected state of instance was never reached"); } /** * Returns the time of next instance for a given instanceTime. * * @param instanceTime time of instance * @param frequency frequency of process/feed */ public static String getNextInstanceTime(String instanceTime, Frequency frequency) { String nextInstanceTime; int minsToAdd = 1; Frequency.TimeUnit timeUnit = frequency.getTimeUnit(); switch (timeUnit) { case minutes: minsToAdd = frequency.getFrequencyAsInt(); break; case hours: minsToAdd = frequency.getFrequencyAsInt()*60; break; case days: minsToAdd = frequency.getFrequencyAsInt()*60*24; break; case months: minsToAdd = frequency.getFrequencyAsInt()*60*24*30; break; default: Assert.fail("Unexpected freqType = " + frequency); break; } nextInstanceTime = TimeUtil.addMinsToTime(instanceTime, minsToAdd); return nextInstanceTime; } }