/**
* 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;
import org.apache.falcon.entity.v0.Frequency;
import org.apache.falcon.entity.v0.feed.ActionType;
import org.apache.falcon.regression.Entities.FeedMerlin;
import org.apache.falcon.regression.core.bundle.Bundle;
import org.apache.falcon.regression.core.helpers.ColoHelper;
import org.apache.falcon.regression.core.response.ServiceResponse;
import org.apache.falcon.regression.core.util.AssertUtil;
import org.apache.falcon.regression.core.util.BundleUtil;
import org.apache.falcon.regression.core.util.TimeUtil;
import org.apache.falcon.regression.core.util.Util;
import org.apache.falcon.regression.testHelper.BaseTestClass;
import org.apache.log4j.Logger;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
* Feed SLA tests.
*/
@Test(groups = { "distributed", "embedded", "sanity" })
public class FeedSLATest extends BaseTestClass {
private ColoHelper cluster = servers.get(0);
private String baseTestDir = cleanAndGetTestDir();
private String feedInputPath = baseTestDir + "/input" + MINUTE_DATE_PATTERN;
private static final Logger LOGGER = Logger.getLogger(FeedSLATest.class);
private FeedMerlin feedMerlin;
private String startTime;
private String endTime;
@BeforeMethod(alwaysRun = true)
public void setup() throws Exception {
Bundle bundle = BundleUtil.readELBundle();
bundles[0] = new Bundle(bundle, cluster);
bundles[0].generateUniqueBundle(this);
bundles[0].setInputFeedDataPath(feedInputPath);
startTime = TimeUtil.getTimeWrtSystemTime(0);
endTime = TimeUtil.addMinsToTime(startTime, 120);
LOGGER.info("Time range between : " + startTime + " and " + endTime);
ServiceResponse response =
prism.getClusterHelper().submitEntity(bundles[0].getClusters().get(0));
AssertUtil.assertSucceeded(response);
feedMerlin = new FeedMerlin(bundles[0].getInputFeedFromBundle());
feedMerlin.setFrequency(new Frequency("1", Frequency.TimeUnit.hours));
}
@AfterMethod(alwaysRun = true)
public void tearDown() {
removeTestClassEntities();
}
/**
* Submit feed with correctly adjusted sla. Response should reflect success.
*
*/
@Test
public void submitValidFeedSLA() throws Exception {
feedMerlin.clearFeedClusters();
feedMerlin.addFeedCluster(new FeedMerlin.FeedClusterBuilder(
Util.readEntityName(bundles[0].getClusters().get(0)))
.withRetention("days(1000000)", ActionType.DELETE)
.withValidity(startTime, endTime)
.build());
//set slaLow and slaHigh
feedMerlin.setSla(new Frequency("3", Frequency.TimeUnit.hours), new Frequency("6", Frequency.TimeUnit.hours));
final ServiceResponse serviceResponse =
prism.getFeedHelper().submitEntity(feedMerlin.toString());
AssertUtil.assertSucceeded(serviceResponse);
}
/**
* Submit feed with slaHigh greater than feed retention. Response should reflect failure.
*
*/
@Test
public void submitFeedWithSLAHigherThanRetention() throws Exception {
feedMerlin.clearFeedClusters();
feedMerlin.addFeedCluster(new FeedMerlin.FeedClusterBuilder(
Util.readEntityName(bundles[0].getClusters().get(0)))
.withRetention((new Frequency("2", Frequency.TimeUnit.hours)).toString(), ActionType.DELETE)
.withValidity(startTime, endTime)
.build());
//set slaLow and slaHigh
feedMerlin.setSla(new Frequency("3", Frequency.TimeUnit.hours), new Frequency("6", Frequency.TimeUnit.hours));
final ServiceResponse serviceResponse =
prism.getFeedHelper().submitEntity(feedMerlin.toString());
String message = "Feed's retention limit: "
+ feedMerlin.getClusters().getClusters().get(0).getRetention().getLimit()
+ " of referenced cluster " + bundles[0].getClusterNames().get(0)
+ " should be more than feed's late arrival cut-off period: "
+ feedMerlin.getSla().getSlaHigh().getTimeUnit()
+ "(" + feedMerlin.getSla().getSlaHigh().getFrequency() + ")"
+ " for feed: " + bundles[0].getInputFeedNameFromBundle();
validate(serviceResponse, message);
}
/**
* Submit feed with slaHigh less than slaLow. Response should reflect failure.
*
*/
@Test
public void submitFeedWithSLAHighLowerthanSLALow() throws Exception {
feedMerlin.clearFeedClusters();
feedMerlin.addFeedCluster(new FeedMerlin.FeedClusterBuilder(
Util.readEntityName(bundles[0].getClusters().get(0)))
.withRetention((new Frequency("6", Frequency.TimeUnit.hours)).toString(), ActionType.DELETE)
.withValidity(startTime, endTime)
.build());
//set slaLow and slaHigh
feedMerlin.setSla(new Frequency("4", Frequency.TimeUnit.hours), new Frequency("2", Frequency.TimeUnit.hours));
final ServiceResponse serviceResponse =
prism.getFeedHelper().submitEntity(feedMerlin.toString());
String message = "slaLow of Feed: " + feedMerlin.getSla().getSlaLow().getTimeUnit() + "("
+ feedMerlin.getSla().getSlaLow().getFrequency() + ")is greater than slaHigh: "
+ feedMerlin.getSla().getSlaHigh().getTimeUnit() + "(" + feedMerlin.getSla().getSlaHigh().getFrequency()
+ ") for cluster: " + bundles[0].getClusterNames().get(0);
validate(serviceResponse, message);
}
/**
* Submit feed with slaHigh and slaLow greater than feed retention. Response should reflect failure.
*
*/
@Test
public void submitFeedWithSLAHighSLALowHigherThanRetention() throws Exception {
feedMerlin.clearFeedClusters();
feedMerlin.addFeedCluster(new FeedMerlin.FeedClusterBuilder(
Util.readEntityName(bundles[0].getClusters().get(0)))
.withRetention((new Frequency("4", Frequency.TimeUnit.hours)).toString(), ActionType.DELETE)
.withValidity(startTime, endTime)
.build());
//set slaLow and slaHigh
feedMerlin.setSla(new Frequency("5", Frequency.TimeUnit.hours), new Frequency("6", Frequency.TimeUnit.hours));
final ServiceResponse serviceResponse =
prism.getFeedHelper().submitEntity(feedMerlin.toString());
String message = "Feed's retention limit: "
+ feedMerlin.getClusters().getClusters().get(0).getRetention().getLimit()
+ " of referenced cluster " + bundles[0].getClusterNames().get(0)
+ " should be more than feed's late arrival cut-off period: "
+ feedMerlin.getSla().getSlaHigh().getTimeUnit() +"(" + feedMerlin.getSla().getSlaHigh().getFrequency()
+ ")" + " for feed: " + bundles[0].getInputFeedNameFromBundle();
validate(serviceResponse, message);
}
/**
* Submit feed with slaHigh and slaLow having equal value. Response should reflect success.
*
*/
@Test
public void submitFeedWithSameSLAHighSLALow() throws Exception {
feedMerlin.clearFeedClusters();
feedMerlin.addFeedCluster(new FeedMerlin.FeedClusterBuilder(
Util.readEntityName(bundles[0].getClusters().get(0)))
.withRetention((new Frequency("7", Frequency.TimeUnit.hours)).toString(), ActionType.DELETE)
.withValidity(startTime, endTime)
.build());
//set slaLow and slaHigh
feedMerlin.setSla(new Frequency("3", Frequency.TimeUnit.hours), new Frequency("3", Frequency.TimeUnit.hours));
final ServiceResponse serviceResponse =
prism.getFeedHelper().submitEntity(feedMerlin.toString());
AssertUtil.assertSucceeded(serviceResponse);
}
private void validate(ServiceResponse response, String message) throws Exception {
AssertUtil.assertFailed(response);
LOGGER.info("Expected message is : " + message);
Assert.assertTrue(response.getMessage().contains(message),
"Correct response was not present in feed schedule. Feed response is : "
+ response.getMessage());
}
}