You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@falcon.apache.org by pi...@apache.org on 2015/10/20 11:37:52 UTC
[1/3] falcon git commit: Add ProcessUpdateTest,
PipelineInstanceDependencyTest and other tests and test fixes.
Contributed by Raghav Gautam and Paul Isaychuk
Repository: falcon
Updated Branches:
refs/heads/master 5a55baed3 -> 9e6d5a6c5
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/triage/PipelineInstanceDependencyTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/triage/PipelineInstanceDependencyTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/triage/PipelineInstanceDependencyTest.java
new file mode 100644
index 0000000..81d5fcc
--- /dev/null
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/triage/PipelineInstanceDependencyTest.java
@@ -0,0 +1,335 @@
+/**
+ * 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.triage;
+
+import org.apache.falcon.entity.v0.EntityType;
+import org.apache.falcon.entity.v0.Frequency;
+import org.apache.falcon.regression.Entities.FeedMerlin;
+import org.apache.falcon.regression.Entities.ProcessMerlin;
+import org.apache.falcon.regression.core.bundle.Bundle;
+import org.apache.falcon.regression.core.helpers.ColoHelper;
+import org.apache.falcon.regression.core.helpers.entity.AbstractEntityHelper;
+import org.apache.falcon.regression.core.util.AssertUtil;
+import org.apache.falcon.regression.core.util.BundleUtil;
+import org.apache.falcon.regression.core.util.EntityLineageUtil;
+import org.apache.falcon.regression.core.util.EntityLineageUtil.PipelineEntityType;
+import org.apache.falcon.regression.core.util.HadoopUtil;
+import org.apache.falcon.regression.core.util.InstanceUtil;
+import org.apache.falcon.regression.core.util.OSUtil;
+import org.apache.falcon.regression.core.util.TimeUtil;
+import org.apache.falcon.regression.testHelper.BaseTestClass;
+import org.apache.falcon.resource.APIResult;
+import org.apache.falcon.resource.InstanceDependencyResult;
+import org.apache.falcon.resource.LineageGraphResult;
+import org.apache.falcon.resource.LineageGraphResult.Edge;
+import org.apache.falcon.resource.SchedulableEntityInstance;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.security.authentication.client.AuthenticationException;
+import org.apache.log4j.Logger;
+import org.apache.oozie.client.CoordinatorAction;
+import org.apache.oozie.client.OozieClient;
+import org.joda.time.DateTime;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * Test for instance dependency endpoint.
+ */
+@Test(groups = "embedded")
+public class PipelineInstanceDependencyTest extends BaseTestClass {
+
+ private ColoHelper cluster = servers.get(0);
+ private FileSystem clusterFS = serverFS.get(0);
+ private OozieClient clusterOC = serverOC.get(0);
+ private String baseTestHDFSDir = cleanAndGetTestDir();
+ private String aggregateWorkflowDir = baseTestHDFSDir + "/aggregator";
+ private String feedInputPath = baseTestHDFSDir + "/input" + MINUTE_DATE_PATTERN;
+ private String feedOutputPath = baseTestHDFSDir + "/output-data" + MINUTE_DATE_PATTERN;
+ private final String startTimeStr = "2010-01-02T01:00Z";
+ private final DateTime startTime = TimeUtil.oozieDateToDate(startTimeStr);
+ private final String endTimeStr = "2010-01-02T01:11Z";
+ private List<String> inputFeedNames, outputFeedNames, processNames;
+ private List<Integer> inputFeedFrequencies;
+ private static final Logger LOGGER = Logger.getLogger(PipelineInstanceDependencyTest.class);
+ private String clusterName;
+
+ private static final Comparator<SchedulableEntityInstance> DEPENDENCY_COMPARATOR =
+ new Comparator<SchedulableEntityInstance>() {
+ @Override
+ public int compare(SchedulableEntityInstance o1, SchedulableEntityInstance o2) {
+ int tagDiff = o1.getTags().compareTo(o2.getTags());
+ if (tagDiff != 0) {
+ return tagDiff;
+ }
+ int clusterDiff = o1.getCluster().compareTo(o2.getCluster());
+ if (clusterDiff != 0) {
+ return clusterDiff;
+ }
+ int typeDiff = o1.getEntityType().compareTo(o2.getEntityType());
+ if (typeDiff != 0) {
+ return typeDiff;
+ }
+ int dateDiff = o1.getInstanceTime().compareTo(o2.getInstanceTime());
+ if (dateDiff != 0) {
+ return dateDiff;
+ }
+ return 0;
+ }
+ };
+ private final Comparator<Edge> edgeComparator =
+ new Comparator<Edge>() {
+ @Override
+ public int compare(Edge o1, Edge o2) {
+ return o1.toString().compareTo(o2.toString());
+ }
+ };
+
+ @BeforeClass(alwaysRun = true)
+ public void createTestData() throws Exception {
+ LOGGER.info("in @BeforeClass");
+ HadoopUtil.uploadDir(clusterFS, aggregateWorkflowDir, OSUtil.RESOURCES_OOZIE);
+ }
+
+ /**
+ * The scenario that we will setup looks like:<br>
+ * inputFeed1 -> process1 -> outputFeed1 -> process2 -> outputFeed2 -> process3 -> outputFeed3.
+ * @throws Exception
+ */
+ @BeforeMethod(alwaysRun = true)
+ public void setup() throws Exception {
+ bundles[0] = BundleUtil.readELBundle();
+ bundles[0] = new Bundle(bundles[0], cluster);
+ bundles[0].generateUniqueBundle(this);
+ clusterName = bundles[0].getClusterNames().get(0);
+ bundles[0].setProcessWorkflow(aggregateWorkflowDir);
+ bundles[0].setProcessValidity(startTimeStr, endTimeStr);
+ bundles[0].setProcessPeriodicity(5, Frequency.TimeUnit.minutes);
+ bundles[0].setInputFeedDataPath(feedInputPath);
+ bundles[0].setOutputFeedPeriodicity(5, Frequency.TimeUnit.minutes);
+ bundles[0].setOutputFeedLocationData(feedOutputPath);
+ bundles[0].submitFeedsScheduleProcess(prism);
+ final String oldInputFeedName = bundles[0].getInputFeedNameFromBundle();
+ final String oldOutputFeedName = bundles[0].getOutputFeedNameFromBundle();
+ final String oldProcessName = bundles[0].getProcessName();
+ inputFeedFrequencies = Arrays.asList(20, 5, 5);
+ inputFeedNames = Arrays.asList(oldInputFeedName, oldOutputFeedName, oldOutputFeedName + "-2");
+ outputFeedNames = Arrays.asList(oldOutputFeedName, oldOutputFeedName + "-2", oldOutputFeedName + "-3");
+ processNames = Arrays.asList(oldProcessName, oldProcessName + "-2", oldProcessName + "-3");
+ List<String> feedOutputPaths = Arrays.asList(
+ feedOutputPath,
+ baseTestHDFSDir + "/output-data-2" + MINUTE_DATE_PATTERN,
+ baseTestHDFSDir + "/output-data-3" + MINUTE_DATE_PATTERN
+ );
+
+ //create second, third process that consumes output of bundle[0]
+ for (int bIndex = 1; bIndex < 3; ++bIndex) {
+ final FeedMerlin outputFeed = new FeedMerlin(bundles[0].getOutputFeedFromBundle());
+ final ProcessMerlin processMerlin = bundles[0].getProcessObject();
+
+ processMerlin.setName(processNames.get(bIndex));
+
+ outputFeed.setDataLocationPath(feedOutputPaths.get(bIndex));
+ outputFeed.setName(outputFeedNames.get(bIndex));
+
+ //rename output feeds before renaming input feeds
+ processMerlin.renameFeeds(Collections.singletonMap(oldOutputFeedName, outputFeedNames.get(bIndex)));
+ processMerlin.renameFeeds(Collections.singletonMap(oldInputFeedName, inputFeedNames.get(bIndex)));
+ AssertUtil.assertSucceeded(prism.getFeedHelper().submitEntity(outputFeed.toString()));
+ AssertUtil.assertSucceeded(prism.getProcessHelper().submitAndSchedule(processMerlin.toString()));
+ }
+
+ for (int index = 0; index < 3; ++index) {
+ InstanceUtil.waitTillInstanceReachState(clusterOC, processNames.get(index), 3,
+ CoordinatorAction.Status.WAITING, EntityType.PROCESS, 5);
+ }
+ LOGGER.info(inputFeedNames.get(0) + "(" + inputFeedFrequencies.get(0) + ") -> *" + processNames.get(0)+ "* -> "
+ + inputFeedNames.get(1) + "(" + inputFeedFrequencies.get(1) + ") -> *" + processNames.get(1)+ "* -> "
+ + inputFeedNames.get(2) + "(" + inputFeedFrequencies.get(2) + ") -> *" + processNames.get(2)+ "* -> "
+ + outputFeedNames.get(2));
+ }
+
+ @AfterMethod(alwaysRun = true)
+ public void tearDown() {
+ removeTestClassEntities();
+ }
+
+ @Test
+ public void processInstanceDependencyTest() throws Exception {
+ final DateTime startTimeMinus20 = startTime.minusMinutes(20);
+
+ for (int index = 0; index < 3; ++index) {
+ List<SchedulableEntityInstance> expectedDependencies = new ArrayList<>();
+ final SchedulableEntityInstance outputInstance =
+ new SchedulableEntityInstance(outputFeedNames.get(index), clusterName, startTime.toDate(),
+ EntityType.FEED);
+ outputInstance.setTags("Output");
+ expectedDependencies.add(outputInstance);
+ for (DateTime dt = new DateTime(startTime); !dt.isBefore(startTimeMinus20);
+ dt = dt.minusMinutes(inputFeedFrequencies.get(index))) {
+ final SchedulableEntityInstance inputInstance =
+ new SchedulableEntityInstance(inputFeedNames.get(index), clusterName, dt.toDate(), EntityType.FEED);
+ inputInstance.setTags("Input");
+ expectedDependencies.add(inputInstance);
+ }
+ InstanceDependencyResult r = prism.getProcessHelper().getInstanceDependencies(processNames.get(index),
+ "?instanceTime=" + startTimeStr, null);
+
+ List<SchedulableEntityInstance> actualDependencies = Arrays.asList(r.getDependencies());
+ Collections.sort(expectedDependencies, DEPENDENCY_COMPARATOR);
+ Collections.sort(actualDependencies, DEPENDENCY_COMPARATOR);
+ Assert.assertEquals(actualDependencies, expectedDependencies,
+ "Unexpected dependencies for process: " + processNames.get(index));
+ }
+ }
+
+ @Test
+ public void inputFeedInstanceDependencyTest() throws Exception {
+ final String inputFeedToTest = inputFeedNames.get(1);
+ final DateTime endTime = TimeUtil.oozieDateToDate(endTimeStr);
+
+ List<SchedulableEntityInstance> expectedDependencies = new ArrayList<>();
+ final SchedulableEntityInstance outputInstance =
+ new SchedulableEntityInstance(processNames.get(0), clusterName, startTime.toDate(), EntityType.PROCESS);
+ outputInstance.setTags("Output");
+ expectedDependencies.add(outputInstance);
+ final int processFrequency = 5;
+ for (DateTime dt = new DateTime(startTime); !dt.isAfter(endTime); dt = dt.plusMinutes(processFrequency)) {
+ final SchedulableEntityInstance inputInstance =
+ new SchedulableEntityInstance(processNames.get(1), clusterName, dt.toDate(), EntityType.PROCESS);
+ inputInstance.setTags("Input");
+ expectedDependencies.add(inputInstance);
+ }
+ InstanceDependencyResult r = prism.getFeedHelper().getInstanceDependencies(inputFeedToTest,
+ "?instanceTime=" + startTimeStr, null);
+
+ List<SchedulableEntityInstance> actualDependencies = Arrays.asList(r.getDependencies());
+ Collections.sort(expectedDependencies, DEPENDENCY_COMPARATOR);
+ Collections.sort(actualDependencies, DEPENDENCY_COMPARATOR);
+ Assert.assertEquals(actualDependencies, expectedDependencies,
+ "Unexpected dependencies for process: " + inputFeedToTest);
+ }
+
+ @Test
+ public void outputFeedInstanceDependencyTest() throws Exception {
+ final String outputFeedToTest = outputFeedNames.get(1);
+ final DateTime endTime = TimeUtil.oozieDateToDate(endTimeStr);
+
+ List<SchedulableEntityInstance> expectedDependencies = new ArrayList<>();
+ final SchedulableEntityInstance outputInstance =
+ new SchedulableEntityInstance(processNames.get(1), clusterName, startTime.toDate(), EntityType.PROCESS);
+ outputInstance.setTags("Output");
+ expectedDependencies.add(outputInstance);
+ final int processFrequency = 5;
+ for (DateTime dt = new DateTime(startTime); !dt.isAfter(endTime); dt = dt.plusMinutes(processFrequency)) {
+ final SchedulableEntityInstance inputInstance =
+ new SchedulableEntityInstance(processNames.get(2), clusterName, dt.toDate(), EntityType.PROCESS);
+ inputInstance.setTags("Input");
+ expectedDependencies.add(inputInstance);
+ }
+ InstanceDependencyResult r = prism.getFeedHelper().getInstanceDependencies(outputFeedToTest,
+ "?instanceTime=" + startTimeStr, null);
+
+ List<SchedulableEntityInstance> actualDependencies = Arrays.asList(r.getDependencies());
+ Collections.sort(expectedDependencies, DEPENDENCY_COMPARATOR);
+ Collections.sort(actualDependencies, DEPENDENCY_COMPARATOR);
+ Assert.assertEquals(actualDependencies, expectedDependencies,
+ "Unexpected dependencies for process: " + outputFeedToTest);
+ }
+
+ /**
+ * Particular check for https://issues.apache.org/jira/browse/FALCON-1317.
+ */
+ @Test
+ public void testInstanceDependencySingleElement()
+ throws URISyntaxException, AuthenticationException, InterruptedException, IOException {
+ InstanceDependencyResult r = prism.getFeedHelper().getInstanceDependencies(outputFeedNames.get(2),
+ "?instanceTime=" + startTimeStr, null);
+ Assert.assertEquals(r.getStatus(), APIResult.Status.SUCCEEDED, "Request shouldn't fail.");
+ List<SchedulableEntityInstance> actualDependencies = Arrays.asList(r.getDependencies());
+ Assert.assertEquals(actualDependencies.size(), 1, "There should be single dependency element.");
+ }
+
+ /**
+ * Run triage for different pipeline feeds and processes.
+ * @param bundleInd pipeline bundle
+ * @param entityType process or feed
+ */
+ @Test(dataProvider = "getParameters")
+ public void testTriageInstance(int bundleInd, EntityType entityType)
+ throws URISyntaxException, AuthenticationException, InterruptedException, IOException {
+ AbstractEntityHelper helper;
+ String entityName;
+ if (entityType == EntityType.FEED) {
+ helper = prism.getFeedHelper();
+ entityName = outputFeedNames.get(bundleInd);
+ } else {
+ helper = prism.getProcessHelper();
+ entityName = processNames.get(bundleInd);
+ }
+ Map<PipelineEntityType, List<String>> entitiesNames = new HashMap<>();
+ entitiesNames.put(PipelineEntityType.PROCESS, processNames);
+ entitiesNames.put(PipelineEntityType.INPUT_FEED, inputFeedNames);
+ entitiesNames.put(PipelineEntityType.OUTPUT_FEED, outputFeedNames);
+ LineageGraphResult expected = EntityLineageUtil.getExpectedResult(bundleInd, entitiesNames,
+ inputFeedFrequencies, entityName, clusterName, startTimeStr);
+ LineageGraphResult actual = helper.getInstanceTriage(entityName,
+ "?start=" + startTimeStr).getTriageGraphs()[0];
+
+ final List<String> expectedVertices = new ArrayList<>(Arrays.asList(expected.getVertices()));
+ final List<Edge> expectedEdges = new ArrayList<>(Arrays.asList(expected.getEdges()));
+ final List<String> actualVertices = Arrays.asList(actual.getVertices());
+ final List<Edge> actualEdges = Arrays.asList(actual.getEdges());
+ Collections.sort(actualVertices);
+ Collections.sort(expectedVertices);
+ Collections.sort(actualEdges, edgeComparator);
+ Collections.sort(expectedEdges, edgeComparator);
+ Assert.assertEquals(actualVertices, expectedVertices,
+ "Actual vertices & expected vertices in triage graph don't match");
+ Assert.assertEquals(actualEdges, expectedEdges,
+ "Actual edges & expected edges in triage graph don't match");
+ }
+
+ @DataProvider
+ public Object[][] getParameters() {
+ return new Object[][]{
+ {0, EntityType.FEED},
+ {0, EntityType.PROCESS},
+ {1, EntityType.FEED},
+ {1, EntityType.PROCESS},
+ {2, EntityType.FEED},
+ {2, EntityType.PROCESS},
+ };
+ }
+
+}
[3/3] falcon git commit: Add ProcessUpdateTest,
PipelineInstanceDependencyTest and other tests and test fixes.
Contributed by Raghav Gautam and Paul Isaychuk
Posted by pi...@apache.org.
Add ProcessUpdateTest, PipelineInstanceDependencyTest and other tests and test fixes. Contributed by Raghav Gautam and Paul Isaychuk
Project: http://git-wip-us.apache.org/repos/asf/falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/falcon/commit/9e6d5a6c
Tree: http://git-wip-us.apache.org/repos/asf/falcon/tree/9e6d5a6c
Diff: http://git-wip-us.apache.org/repos/asf/falcon/diff/9e6d5a6c
Branch: refs/heads/master
Commit: 9e6d5a6c58d99479cc58c11b5b05b11bf8d90821
Parents: 5a55bae
Author: Paul Isaychuk <pi...@apache.org>
Authored: Thu Oct 15 14:15:58 2015 +0300
Committer: Paul Isaychuk <pi...@apache.org>
Committed: Tue Oct 20 11:46:31 2015 +0300
----------------------------------------------------------------------
falcon-regression/CHANGES.txt | 3 +
.../regression/Entities/ProcessMerlin.java | 9 +
.../helpers/entity/AbstractEntityHelper.java | 10 +
.../regression/core/util/EntityLineageUtil.java | 63 ++++
.../regression/core/util/InstanceUtil.java | 40 ++-
.../regression/core/util/KerberosHelper.java | 9 +
.../falcon/regression/core/util/OozieUtil.java | 52 +++
.../falcon/regression/core/util/Util.java | 22 ++
.../ui/search/AbstractSearchPage.java | 69 +++-
.../regression/ui/search/ClusterWizardPage.java | 40 +--
.../regression/ui/search/EntityWizardPage.java | 94 ++++++
.../regression/ui/search/FeedWizardPage.java | 27 +-
.../falcon/regression/ui/search/LoginPage.java | 1 +
.../regression/ui/search/MirrorWizardPage.java | 13 +-
.../falcon/regression/ui/search/PageHeader.java | 30 +-
.../regression/ui/search/ProcessWizardPage.java | 37 +-
.../falcon/regression/ExternalFSTest.java | 2 +-
.../falcon/regression/FeedReplicationTest.java | 109 +++++-
.../regression/ProcessInstanceStatusTest.java | 39 +++
.../falcon/regression/ProcessUpdateTest.java | 112 +++++++
.../falcon/regression/TestngListener.java | 2 +-
.../falcon/regression/hive/dr/HiveDRTest.java | 118 ++++---
.../falcon/regression/hive/dr/HiveDbDRTest.java | 61 ++--
.../regression/hive/dr/RecipeExecLocation.java | 63 ++++
.../lineage/ListProcessInstancesTest.java | 27 +-
.../regression/searchUI/ClusterSetupTest.java | 48 ++-
.../regression/searchUI/FeedSetupTest.java | 61 ++--
.../regression/searchUI/HomePageTest.java | 4 +-
.../searchUI/MirrorSourceTargetOptionsTest.java | 2 +
.../falcon/regression/searchUI/MirrorTest.java | 76 ++++-
.../regression/searchUI/ProcessSetupTest.java | 65 ++--
.../regression/security/FalconClientTest.java | 7 +-
.../triage/PipelineInstanceDependencyTest.java | 335 +++++++++++++++++++
33 files changed, 1365 insertions(+), 285 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/CHANGES.txt
----------------------------------------------------------------------
diff --git a/falcon-regression/CHANGES.txt b/falcon-regression/CHANGES.txt
index 5ea229a..d285661 100644
--- a/falcon-regression/CHANGES.txt
+++ b/falcon-regression/CHANGES.txt
@@ -5,6 +5,9 @@ Trunk (Unreleased)
INCOMPATIBLE CHANGES
NEW FEATURES
+ FALCON-1546 Add ProcessUpdateTest, PipelineInstanceDependencyTest and other tests and test fixes
+ (Raghav Gautam and Paul Isaychuk via Paul Isaychuk)
+
FALCON-1387 Add Instance Dependency API Test(Pragya Mittal via Ajay Yadava)
FALCON-1382 Add a test for feed retention to make sure that data directory is not deleted (Paul Isaychuk)
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/Entities/ProcessMerlin.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/Entities/ProcessMerlin.java b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/Entities/ProcessMerlin.java
index b905bee..7607aa6 100644
--- a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/Entities/ProcessMerlin.java
+++ b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/Entities/ProcessMerlin.java
@@ -213,6 +213,15 @@ public class ProcessMerlin extends Process {
return this;
}
+ public String getProperty(String name) {
+ for (Property property : properties.getProperties()) {
+ if (property.getName().equals(name)) {
+ return property.getValue();
+ }
+ }
+ return null;
+ }
+
@Override
public String toString() {
try {
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/helpers/entity/AbstractEntityHelper.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/helpers/entity/AbstractEntityHelper.java b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/helpers/entity/AbstractEntityHelper.java
index 83d06a2..e406cae 100644
--- a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/helpers/entity/AbstractEntityHelper.java
+++ b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/helpers/entity/AbstractEntityHelper.java
@@ -38,6 +38,7 @@ import org.apache.falcon.resource.FeedInstanceResult;
import org.apache.falcon.resource.InstanceDependencyResult;
import org.apache.falcon.resource.InstancesResult;
import org.apache.falcon.resource.InstancesSummaryResult;
+import org.apache.falcon.resource.TriageResult;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.security.authentication.client.AuthenticationException;
@@ -554,6 +555,15 @@ public abstract class AbstractEntityHelper {
}
/**
+ * Retrieves instance triage.
+ */
+ public TriageResult getInstanceTriage(String entityName, String params)
+ throws AuthenticationException, IOException, URISyntaxException, InterruptedException {
+ String url = createUrl(this.hostname + URLS.INSTANCE_TRIAGE.getValue(), getEntityType(), entityName);
+ return (TriageResult) InstanceUtil.createAndSendRequestProcessInstance(url, params, allColo, null);
+ }
+
+ /**
* Lists all entities which are tagged by a given pipeline.
* @param pipeline filter
* @return service response
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/EntityLineageUtil.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/EntityLineageUtil.java b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/EntityLineageUtil.java
index fc42cf5..2df474d 100644
--- a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/EntityLineageUtil.java
+++ b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/EntityLineageUtil.java
@@ -20,10 +20,14 @@ package org.apache.falcon.regression.core.util;
import org.apache.falcon.resource.LineageGraphResult;
import org.apache.log4j.Logger;
+import org.joda.time.DateTime;
import org.testng.Assert;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
import java.util.Set;
@@ -34,6 +38,13 @@ public final class EntityLineageUtil{
private static final Logger LOGGER = Logger.getLogger(EntityLineageUtil.class);
+ /**
+ * Enum to represent entity role in pipeline.
+ */
+ public enum PipelineEntityType {
+ PROCESS, INPUT_FEED, OUTPUT_FEED
+ }
+
private EntityLineageUtil() {
throw new AssertionError("Instantiating utility class...");
}
@@ -61,5 +72,57 @@ public final class EntityLineageUtil{
Assert.assertEquals(expectedVerticesSet, actualVerticesSet, "Vertices dont match");
}
+ /**
+ * Produces list of expected vertices and edges in triage result.
+ */
+ public static LineageGraphResult getExpectedResult(int bundleIndx,
+ Map<PipelineEntityType, List<String>> entityNamesMap,
+ List<Integer> inputFeedFrequencies, String entityName,
+ String clusterName, String startTime) {
+ List<String> processNames = entityNamesMap.get(PipelineEntityType.PROCESS);
+ List<String> inputFeedNames = entityNamesMap.get(PipelineEntityType.INPUT_FEED);
+ List<String> outputFeedNames = entityNamesMap.get(PipelineEntityType.OUTPUT_FEED);
+ List<String> vertices = new ArrayList<>();
+ List<LineageGraphResult.Edge> edges = new ArrayList<>();
+ final String startTimeMinus20 = TimeUtil.addMinsToTime(startTime, -20);
+ String vertexTemplate = "name: %s, type: %s, cluster: %s, instanceTime: %s, tags: %s";
+ for (int i = 0; i <= bundleIndx; ++i) {
+ //add vertex of i-th bundle process
+ boolean isTerminalInstance = processNames.contains(entityName) && i == bundleIndx;
+ String tag = isTerminalInstance ? "[WAITING]" : "Output[WAITING]";
+ final String processVertex = String.format(vertexTemplate,
+ processNames.get(i), "PROCESS", clusterName, startTime, tag);
+ vertices.add(processVertex);
+
+ //add all input feed vertices & edges for i-th bundle
+ LineageGraphResult.Edge edge;
+ String feedVertex;
+ for (DateTime dt = new DateTime(startTime); !dt.isBefore(new DateTime(startTimeMinus20));
+ dt = dt.minusMinutes(inputFeedFrequencies.get(i))) {
+ feedVertex = String.format(vertexTemplate, inputFeedNames.get(i), "FEED",
+ clusterName, TimeUtil.dateToOozieDate(dt.toDate()), "Input[MISSING]");
+ edge = new LineageGraphResult.Edge(feedVertex, processVertex, "consumed by");
+ vertices.add(feedVertex);
+ edges.add(edge);
+ }
+ //add output feed edge for i-th bundle
+ tag = (outputFeedNames.contains(entityName) && i == bundleIndx) ? "[MISSING]" : "Input[MISSING]";
+ feedVertex = String.format(vertexTemplate, outputFeedNames.get(i), "FEED", clusterName, startTime, tag);
+ isTerminalInstance = i == bundleIndx && outputFeedNames.contains(entityName);
+ if (i < bundleIndx || isTerminalInstance) {
+ edge = new LineageGraphResult.Edge(processVertex, feedVertex, "produces");
+ edges.add(edge);
+ }
+ //add output feed vertex only if it is terminal; it will be added as the input for next bundle otherwise
+ if (isTerminalInstance) {
+ vertices.add(feedVertex);
+ }
+ }
+ LineageGraphResult lineageGraphResult = new LineageGraphResult();
+ lineageGraphResult.setVertices(vertices.toArray(new String[vertices.size()]));
+ lineageGraphResult.setEdges(edges.toArray(new LineageGraphResult.Edge[edges.size()]));
+ return lineageGraphResult;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/InstanceUtil.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/InstanceUtil.java b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/InstanceUtil.java
index 10463c2..3d05ae9 100644
--- a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/InstanceUtil.java
+++ b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/InstanceUtil.java
@@ -36,6 +36,7 @@ import org.apache.falcon.resource.InstanceDependencyResult;
import org.apache.falcon.resource.InstancesResult;
import org.apache.falcon.resource.InstancesSummaryResult;
import org.apache.falcon.resource.SchedulableEntityInstance;
+import org.apache.falcon.resource.TriageResult;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.authentication.client.AuthenticationException;
import org.apache.http.HttpResponse;
@@ -96,8 +97,10 @@ public final class InstanceUtil {
result = new InstancesSummaryResult(APIResult.Status.FAILED, responseString);
}else if (url.contains("/listing/")) {
result = new FeedInstanceResult(APIResult.Status.FAILED, responseString);
- }else if (url.contains("/dependencies/")) {
+ }else if (url.contains("instance/dependencies")) {
result = new InstanceDependencyResult(APIResult.Status.FAILED, responseString);
+ }else if (url.contains("instance/triage")) {
+ result = new TriageResult(APIResult.Status.FAILED, responseString);
}else {
result = new InstancesResult(APIResult.Status.FAILED, responseString);
}
@@ -126,10 +129,7 @@ public final class InstanceUtil {
public Date deserialize(JsonElement json, Type t, JsonDeserializationContext c) {
return new DateTime(json.getAsString()).toDate();
}
- }).create().fromJson(responseString,
- url.contains("/listing/") ? FeedInstanceResult.class : url.contains("/summary/")
- ? InstancesSummaryResult.class : url.contains("/dependencies/")
- ? InstanceDependencyResult.class : InstancesResult.class);
+ }).create().fromJson(responseString, getClassOfResult(url));
} catch (JsonSyntaxException e) {
Assert.fail("Not a valid json:\n" + responseString);
}
@@ -140,6 +140,25 @@ public final class InstanceUtil {
}
/**
+ * Returns API result class matching to API request url.
+ */
+ private static Class<? extends APIResult> getClassOfResult(String url) {
+ final Class<? extends APIResult> classOfResult;
+ if (url.contains("/listing/")) {
+ classOfResult = FeedInstanceResult.class;
+ } else if (url.contains("/summary/")) {
+ classOfResult = InstancesSummaryResult.class;
+ } else if (url.contains("instance/dependencies")) {
+ classOfResult = InstanceDependencyResult.class;
+ } else if (url.contains("instance/triage")) {
+ classOfResult = TriageResult.class;
+ } else {
+ classOfResult = InstancesResult.class;
+ }
+ return classOfResult;
+ }
+
+ /**
* Checks if API response reflects success and if it's instances match to expected status.
*
* @param instancesResult - kind of response from API which should contain information about
@@ -717,8 +736,8 @@ public final class InstanceUtil {
* @throws ParseException
*/
public static void assertProcessInstances(InstanceDependencyResult instancesResult, OozieClient oozieClient,
- String bundleID, String time) throws OozieClientException,
- JSONException, ParseException {
+ String bundleID, String time)
+ throws OozieClientException, ParseException, JSONException {
List<String> inputPath = new ArrayList<>();
List<String> outputPath = new ArrayList<>();
SchedulableEntityInstance[] instances = instancesResult.getDependencies();
@@ -808,13 +827,10 @@ public final class InstanceUtil {
* @param processName process name for given bundle
* @param tag Input/Output
* @param expectedInstances instance for given instanceTime.
- * @throws JSONException
* @throws ParseException
- * @throws OozieClientException
*/
public static void assertFeedInstances(InstanceDependencyResult instancesResult, String processName, String tag,
- List<String> expectedInstances)
- throws OozieClientException, JSONException, ParseException {
+ List<String> expectedInstances) throws ParseException {
List<String> actualInstances = new ArrayList<>();
SchedulableEntityInstance[] instances = instancesResult.getDependencies();
LOGGER.info("instances: " + Arrays.toString(instances));
@@ -833,7 +849,7 @@ public final class InstanceUtil {
Set<String> expectedInstancesSet = new HashSet<>(expectedInstances);
Set<String> actualInstancesSet = new HashSet<>(actualInstances);
- Assert.assertEquals(expectedInstancesSet, actualInstancesSet, "Instances dont match");
+ Assert.assertEquals(expectedInstancesSet, actualInstancesSet, "Instances don't match");
}
}
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/KerberosHelper.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/KerberosHelper.java b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/KerberosHelper.java
index 9d028fa..c9f540f 100644
--- a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/KerberosHelper.java
+++ b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/KerberosHelper.java
@@ -18,6 +18,7 @@
package org.apache.falcon.regression.core.util;
+import org.apache.commons.exec.CommandLine;
import org.apache.falcon.regression.core.enumsAndConstants.MerlinConstants;
import org.apache.hadoop.security.UserGroupInformation;
@@ -41,6 +42,14 @@ public final class KerberosHelper {
getKeyTab(user));
}
+ /**
+ * Switches user in kerberos.
+ */
+ public static void initUserWithKeytab(String user){
+ ExecUtil.executeCommand(new CommandLine("sudo").addArgument("kinit").addArgument(getPrincipal(user))
+ .addArgument("-k").addArgument("-t").addArgument(getKeyTab(user)));
+ }
+
private static String getKeyTab(String user) {
return MerlinConstants.getKeytabForUser(user);
}
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/OozieUtil.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/OozieUtil.java b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/OozieUtil.java
index 5e2c7b2..ae96044 100644
--- a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/OozieUtil.java
+++ b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/OozieUtil.java
@@ -37,6 +37,10 @@ import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.json.JSONException;
import org.testng.Assert;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -45,6 +49,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@@ -754,4 +759,51 @@ public final class OozieUtil {
}
return conf;
}
+
+ /**
+ * Method retrieves and parses replication coordinator action workflow definition and checks whether specific
+ * properties are present in list of workflow args or not.
+ * @param workflowDefinition workflow definition
+ * @param actionName action within workflow, e.g pre-processing, replication etc.
+ * @param propMap specific properties which are expected to be in arg list
+ * @return true if all keys and values are present, false otherwise
+ */
+ public static boolean propsArePresentInWorkflow(String workflowDefinition, String actionName,
+ HashMap<String, String> propMap) {
+ //get action definition
+ Document definition = Util.convertStringToDocument(workflowDefinition);
+ Assert.assertNotNull(definition, "Workflow definition shouldn't be null.");
+ NodeList actions = definition.getElementsByTagName("action");
+ Element action = null;
+ for (int i = 0; i < actions.getLength(); i++) {
+ Node node = actions.item(i);
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ action = (Element) node;
+ if (action.getAttribute("name").equals(actionName)) {
+ break;
+ }
+ action = null;
+ }
+ }
+ Assert.assertNotNull(action, actionName + " action not found.");
+
+ //retrieve and checks whether properties are present in workflow args
+ Element javaElement = (Element) action.getElementsByTagName("java").item(0);
+ NodeList args = javaElement.getElementsByTagName("arg");
+ int counter = 0;
+ String key = null;
+ for (int i = 0; i < args.getLength(); i++) {
+ Node node = args.item(i);
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ String argKey = node.getTextContent().replace("-", "");
+ if (key != null && propMap.get(key).equals(argKey)) {
+ counter++;
+ key = null;
+ } else if (key == null && propMap.containsKey(argKey)) {
+ key = argKey;
+ }
+ }
+ }
+ return counter == propMap.size();
+ }
}
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/Util.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/Util.java b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/Util.java
index 83547e7..ccd083b 100644
--- a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/Util.java
+++ b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/Util.java
@@ -46,6 +46,7 @@ import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.testng.Assert;
+import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@@ -54,6 +55,8 @@ import javax.jms.MapMessage;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
@@ -391,6 +394,7 @@ public final class Util {
INSTANCE_RERUN("/api/instance/rerun"),
INSTANCE_SUMMARY("/api/instance/summary"),
INSTANCE_PARAMS("/api/instance/params"),
+ INSTANCE_TRIAGE("/api/instance/triage"),
INSTANCE_LIST("/api/instance/list"),
INSTANCE_LISTING("/api/instance/listing"),
INSTANCE_LOGS("/api/instance/logs"),
@@ -563,6 +567,24 @@ public final class Util {
}
/**
+ * Converts string to xml document.
+ * @param xmlStr string representation
+ * @return document representation.
+ */
+ public static Document convertStringToDocument(String xmlStr) {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder;
+ try {
+ builder = factory.newDocumentBuilder();
+ Document doc = builder.parse(new InputSource(new StringReader(xmlStr)));
+ return doc;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
* Sends api requests.
* @param url target url
* @param method request method
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/AbstractSearchPage.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/AbstractSearchPage.java b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/AbstractSearchPage.java
index d956549..ab73092 100644
--- a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/AbstractSearchPage.java
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/AbstractSearchPage.java
@@ -20,14 +20,15 @@ package org.apache.falcon.regression.ui.search;
import com.google.common.util.concurrent.SimpleTimeLimiter;
import com.google.common.util.concurrent.TimeLimiter;
-import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.commons.lang3.tuple.MutablePair;
import org.apache.falcon.regression.core.enumsAndConstants.MerlinConstants;
import org.apache.falcon.regression.core.util.TimeUtil;
import org.apache.falcon.regression.ui.pages.Page;
import org.apache.log4j.Logger;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
+import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
@@ -50,11 +51,14 @@ public abstract class AbstractSearchPage extends Page {
public static final String UI_URL = MerlinConstants.PRISM_URL;
private static final Logger LOGGER = Logger.getLogger(AbstractSearchPage.class);
public static final int PAGELOAD_TIMEOUT_THRESHOLD = 10;
+ public static final int ALERT_LIFETIME = 3000;
public AbstractSearchPage(WebDriver driver) {
super(driver);
waitForAngularToFinish();
+ LOGGER.info("Going to initialize Page Header.");
pageHeader = PageFactory.initElements(driver, PageHeader.class);
+ LOGGER.info("Initialization done.");
}
private PageHeader pageHeader;
@@ -163,13 +167,54 @@ public abstract class AbstractSearchPage extends Page {
public String getActiveAlertText() {
if (waitForAlert()) {
waitForAngularToFinish();
- return driver.findElement(By.xpath("//div[@class='messages notifs']/div[last()]")).getText();
+ String script = "return $('div.messages.notifs > div:last-child').text();";
+ String message = (String)((JavascriptExecutor)driver).executeScript(script);
+ return message.trim();
} else {
return null;
}
}
/**
+ * Wait for active alert. Check it's lifetime (the period when alert is displayed).
+ */
+ public void validateAlertLifetime() {
+ final WebElement alertsBlock = driver.findElement(By.xpath("//div[@class='messages notifs']"));
+ try {
+ final MutablePair<Long, Long> pair = new MutablePair<>(Long.MAX_VALUE, Long.MAX_VALUE);
+ // wait 5 seconds for alert to start blinking and record time of first blink
+ new WebDriverWait(driver, 5, 100).until(new ExpectedCondition<Boolean>() {
+ @Nullable
+ @Override
+ public Boolean apply(WebDriver webDriver) {
+ String style = alertsBlock.getAttribute("style");
+ if ((style.contains("opacity") && !style.contains("opacity: 1;"))
+ || style.contains("display: block;")) {
+ pair.setLeft(System.currentTimeMillis());
+ return true;
+ }
+ return false;
+ }
+ });
+ // wait 5 seconds for alert to stop blinking and record time of stoppage
+ for (int i = 0; i < ALERT_LIFETIME + 3000; i += 100) {
+ String style = alertsBlock.getAttribute("style");
+ if (style.contains("display: none;")) {
+ pair.setRight(Math.min(System.currentTimeMillis(), pair.getRight()));
+ } else {
+ pair.setRight(Long.MAX_VALUE);
+ }
+ TimeUtil.sleepSeconds(0.1);
+ }
+ long diff = pair.getRight() - pair.getLeft();
+ LOGGER.info(String.format("Alert was live %d millis.", pair.getRight() - pair.getLeft()));
+ Assert.assertTrue(ALERT_LIFETIME <= diff, "Alert was present for too short period of time");
+ } catch (TimeoutException e) {
+ Assert.fail("Alert didn't appear in 5 seconds.");
+ }
+ }
+
+ /**
* Wait for active alert.
* @return true is alert is present
*/
@@ -181,12 +226,8 @@ public abstract class AbstractSearchPage extends Page {
@Override
public Boolean apply(WebDriver webDriver) {
String style = alertsBlock.getAttribute("style");
- if (style.contains("opacity") && !style.contains("opacity: 1;")) {
- String alert = alertsBlock.findElement(By.xpath("./div[last()]")).getText();
- return StringUtils.isNotEmpty(alert);
- } else {
- return false;
- }
+ return (style.contains("opacity") && !style.contains("opacity: 1;"))
+ || style.contains("display: block;");
}
});
return true;
@@ -196,6 +237,18 @@ public abstract class AbstractSearchPage extends Page {
}
/**
+ * Performs simple check of element presence.
+ */
+ public WebElement getElementOrNull(String xpath) {
+ try {
+ return driver.findElement(By.xpath(xpath));
+ } catch (NoSuchElementException ignored) {
+ return null;
+ }
+ }
+
+
+ /**
* Method imitates click on check box. If click is not performed method retries the click.
* @param expectedState whether check box is expected to be enabled or not after click.
*/
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/ClusterWizardPage.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/ClusterWizardPage.java b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/ClusterWizardPage.java
index 0fbfc38..bcada4a 100644
--- a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/ClusterWizardPage.java
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/ClusterWizardPage.java
@@ -38,7 +38,7 @@ import org.testng.Assert;
import java.util.List;
/** Page object of the Cluster creation page. */
-public class ClusterWizardPage extends AbstractSearchPage {
+public class ClusterWizardPage extends EntityWizardPage {
private static final Logger LOGGER = Logger.getLogger(ClusterWizardPage.class);
@FindBys({
@FindBy(className = "mainUIView"),
@@ -53,12 +53,8 @@ public class ClusterWizardPage extends AbstractSearchPage {
private WebElement previous;
@FindBy(xpath = "//a[contains(text(), 'Cancel')]")
private WebElement cancel;
- @FindBy(id = "cluster.editXML")
- private WebElement editXML;
@FindBy(xpath = "//div[contains(@class, 'clusterSummaryRow')][h4]")
private WebElement summaryBox;
- @FindBy(xpath = "//div[contains(@class, 'xmlPreviewContainer')]//textarea")
- private WebElement xmlPreview;
public ClusterWizardPage(WebDriver driver) {
super(driver);
@@ -273,21 +269,6 @@ public class ClusterWizardPage extends AbstractSearchPage {
return false;
}
- public ClusterMerlin getXmlPreview() {
- //preview block fetches changes slower then they appear on the form
- waitForAngularToFinish();
- String previewData = xmlPreview.getAttribute("value");
- return new ClusterMerlin(previewData);
- }
-
- public void setClusterXml(String clusterXml) {
- clickEditXml(true);
- xmlPreview.clear();
- xmlPreview.sendKeys(clusterXml);
- waitForAngularToFinish();
- clickEditXml(false);
- }
-
/**
* Retrieves hte value of the summary box and parses it to cluster properties.
* @param draft empty cluster to contain all properties.
@@ -402,16 +383,6 @@ public class ClusterWizardPage extends AbstractSearchPage {
}
/**
- * Clicks on editXml button.
- */
- public void clickEditXml(boolean shouldBeEnabled) {
- editXML.click();
- String disabled = xmlPreview.getAttribute("disabled");
- Assert.assertEquals(disabled == null, shouldBeEnabled,
- "Xml preview should be " + (shouldBeEnabled ? "enabled" : "disabled"));
- }
-
- /**
* Click on next button which is the same as finish step 1.
*/
public void clickNext() {
@@ -486,4 +457,13 @@ public class ClusterWizardPage extends AbstractSearchPage {
}
}
+ @Override
+ public WebElement getEditXMLButton() {
+ return driver.findElement(By.id("cluster.editXML"));
+ }
+
+ @Override
+ public ClusterMerlin getEntityFromXMLPreview() {
+ return new ClusterMerlin(getXMLPreview());
+ }
}
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/EntityWizardPage.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/EntityWizardPage.java b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/EntityWizardPage.java
new file mode 100644
index 0000000..72c03cf
--- /dev/null
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/EntityWizardPage.java
@@ -0,0 +1,94 @@
+/**
+ * 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.ui.search;
+
+import org.apache.falcon.entity.v0.Entity;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.testng.Assert;
+
+/**
+ * https://issues.apache.org/jira/browse/FALCON-1546.
+ * Parent class for cluster, feed and process wizard pages.
+ */
+public abstract class EntityWizardPage extends AbstractSearchPage {
+ @FindBy(xpath = "//i[contains(@class, 'pointer')]")
+ protected WebElement xmlPreviewPointer;
+ protected WebElement xmlPreview = null;
+
+ public EntityWizardPage(WebDriver driver) {
+ super(driver);
+ }
+
+ /**
+ * Expand/collapse xml preview.
+ * @param shouldBeExpanded should preview be expanded or collapsed.
+ */
+ public void clickXMLPreview(boolean shouldBeExpanded) {
+ if (isXmlPreviewExpanded() != shouldBeExpanded) {
+ xmlPreviewPointer.click();
+ }
+ Assert.assertEquals(isXmlPreviewExpanded(), shouldBeExpanded,
+ "Xml preview should be " + (shouldBeExpanded ? " expanded." : " collapsed."));
+ }
+
+ /**
+ * @return true if xml preview exists and is displayed, false otherwise.
+ */
+ public boolean isXmlPreviewExpanded() {
+ xmlPreview = getElementOrNull("//textarea[@ng-model='prettyXml']");
+ return xmlPreview != null && xmlPreview.isDisplayed();
+ }
+
+ public String getXMLPreview() {
+ //preview block fetches changes slower then they appear on the form
+ waitForAngularToFinish();
+ clickXMLPreview(true);
+ return xmlPreview.getAttribute("value");
+ }
+
+ public abstract Entity getEntityFromXMLPreview();
+
+ /**
+ * Pushes xml into xml preview block.
+ * @param xml entity definition
+ */
+ public void setXmlPreview(String xml) {
+ clickEditXml(true);
+ xmlPreview.clear();
+ xmlPreview.sendKeys(xml);
+ waitForAngularToFinish();
+ clickEditXml(false);
+ }
+
+ /**
+ * Clicks on editXml button.
+ */
+ public void clickEditXml(boolean shouldBeEnabled) {
+ waitForAngularToFinish();
+ clickXMLPreview(true);
+ getEditXMLButton().click();
+ String disabled = xmlPreview.getAttribute("disabled");
+ Assert.assertEquals(disabled == null, shouldBeEnabled,
+ "Xml preview should be " + (shouldBeEnabled ? "enabled" : "disabled"));
+ }
+
+ public abstract WebElement getEditXMLButton();
+}
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/FeedWizardPage.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/FeedWizardPage.java b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/FeedWizardPage.java
index f3a107c..3dfab38 100644
--- a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/FeedWizardPage.java
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/FeedWizardPage.java
@@ -34,7 +34,7 @@ import java.util.Date;
import java.util.List;
/** Page object of the Feed creation page. */
-public class FeedWizardPage extends AbstractSearchPage {
+public class FeedWizardPage extends EntityWizardPage {
private static final Logger LOGGER = Logger.getLogger(FeedWizardPage.class);
@@ -83,17 +83,9 @@ public class FeedWizardPage extends AbstractSearchPage {
})
private WebElement saveFeedButton;
- @FindBys({
- @FindBy(id = "feed.editXML")
- })
- private WebElement editXmlButton;
-
@FindBy(xpath = "//a[contains(.,'Cancel')]")
private WebElement cancelButton;
- @FindBy(xpath = "//textarea[@ng-model='prettyXml']")
- private WebElement feedXml;
-
public FeedWizardPage(WebDriver driver) {
super(driver);
}
@@ -327,11 +319,6 @@ public class FeedWizardPage extends AbstractSearchPage {
cancelButton.click();
}
- public void clickEditXml(){
- waitForAngularToFinish();
- editXmlButton.click();
- }
-
public void clickCatalogStorageButton(){
catalogStorageButton.click();
waitForAngularToFinish();
@@ -652,14 +639,14 @@ public class FeedWizardPage extends AbstractSearchPage {
waitForAlert();
}
- public FeedMerlin getFeedMerlinFromFeedXml() throws Exception{
- waitForAngularToFinish();
- return FeedMerlin.fromString(feedXml.getAttribute("value"));
+ @Override
+ public FeedMerlin getEntityFromXMLPreview() {
+ return FeedMerlin.fromString(getXMLPreview());
}
- public void setFeedXml(String xml) throws Exception{
- feedXml.clear();
- feedXml.sendKeys(xml);
+ @Override
+ public WebElement getEditXMLButton() {
+ return driver.findElement(By.id("feed.editXML"));
}
}
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/LoginPage.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/LoginPage.java b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/LoginPage.java
index 3193d21..5b261fb 100644
--- a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/LoginPage.java
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/LoginPage.java
@@ -46,6 +46,7 @@ public class LoginPage extends AbstractSearchPage {
public static LoginPage open(WebDriver driver) {
driver.get(UI_URL);
+ LOGGER.info("Opened a URL: " + UI_URL);
return PageFactory.initElements(driver, LoginPage.class);
}
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/MirrorWizardPage.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/MirrorWizardPage.java b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/MirrorWizardPage.java
index 6dfa1ca..f990c92 100644
--- a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/MirrorWizardPage.java
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/MirrorWizardPage.java
@@ -278,7 +278,12 @@ public class MirrorWizardPage extends AbstractSearchPage {
return new ClusterBlock("Target");
}
- public void applyRecipe(RecipeMerlin recipe) {
+ /**
+ * Populates hive dr UI with parameters from recipe.
+ * @param recipe recipe
+ * @param overwriteDefaults should it overwrite HiveDR default values automatically picked up by UI
+ */
+ public void applyRecipe(RecipeMerlin recipe, boolean overwriteDefaults) {
final ClusterMerlin srcCluster = recipe.getSrcCluster();
final ClusterMerlin tgtCluster = recipe.getTgtCluster();
setName(recipe.getName());
@@ -303,8 +308,10 @@ public class MirrorWizardPage extends AbstractSearchPage {
setHiveReplicationMaxMaps(recipe.getReplicationMaxMaps());
setMaxEvents(recipe.getMaxEvents());
setHiveMaxBandwidth(recipe.getMapBandwidth());
- setSourceInfo(recipe.getSrcCluster());
- setTargetInfo(recipe.getTgtCluster());
+ if (overwriteDefaults) {
+ setSourceInfo(recipe.getSrcCluster());
+ setTargetInfo(recipe.getTgtCluster());
+ }
break;
default:
break;
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/PageHeader.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/PageHeader.java b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/PageHeader.java
index 2a75b20..7f87091 100644
--- a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/PageHeader.java
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/PageHeader.java
@@ -159,8 +159,8 @@ public class PageHeader {
//checking if logged-in username is displayed
if (!MerlinConstants.IS_SECURE) {
UIAssert.assertDisplayed(getLogoutButton(), "Logout button");
+ AssertUtil.assertNotEmpty(getLoggedInUser(), "Expecting logged-in username.");
}
- AssertUtil.assertNotEmpty(getLoggedInUser(), "Expecting logged-in username.");
//create button navigation
doCreateCluster();
@@ -249,7 +249,33 @@ public class PageHeader {
}
private WebElement getLogoutButton() {
- return loginHeaderBox.findElements(By.tagName("button")).get(1);
+ return loginHeaderBox.findElements(By.xpath("button[@ng-click='logOut()']")).get(0);
+ }
+
+ private WebElement getNotificationButton() {
+ return loginHeaderBox.findElements(By.xpath("button[@ng-click='notify()']")).get(0);
+ }
+
+ /**
+ * Validates number of notifications contained by notification bar and last notification message.
+ */
+ public void validateNotificationCountAndCheckLast(int count, String message) {
+ WebElement notificationButton = getNotificationButton();
+ notificationButton.click();
+ waitForAngularToFinish();
+
+ // Test notifications dropdown visibility
+ WebElement notificationDropdown = notificationButton.findElement(By.className("messages"));
+ Assert.assertTrue(notificationDropdown.getAttribute("style").contains("display: block;"),
+ "Notifications are not visible.");
+
+ // Test validity of number of notifications
+ List<WebElement> notifications = notificationDropdown.findElements(By.xpath("div"));
+ Assert.assertEquals(notifications.size() - 1, count, "Invalid notification count.");
+
+ // Test validity of last notification
+ String lastNotification = notifications.get(0).getText();
+ Assert.assertTrue(lastNotification.contains(message), "Invalid last notification text.");
}
public LoginPage doLogout() {
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/ProcessWizardPage.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/ProcessWizardPage.java b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/ProcessWizardPage.java
index 706328f..5dcd700 100644
--- a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/ProcessWizardPage.java
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/ProcessWizardPage.java
@@ -32,8 +32,8 @@ import org.apache.falcon.entity.v0.process.Output;
import org.apache.falcon.entity.v0.process.Outputs;
import org.apache.falcon.entity.v0.process.PolicyType;
import org.apache.falcon.entity.v0.process.Retry;
-import org.apache.falcon.entity.v0.process.Workflow;
import org.apache.falcon.entity.v0.process.Validity;
+import org.apache.falcon.entity.v0.process.Workflow;
import org.apache.falcon.regression.Entities.ProcessMerlin;
import org.apache.falcon.regression.core.util.UIAssert;
import org.apache.log4j.Logger;
@@ -52,7 +52,7 @@ import java.util.List;
import java.util.TimeZone;
/** Page object of the Process creation page. */
-public class ProcessWizardPage extends AbstractSearchPage {
+public class ProcessWizardPage extends EntityWizardPage {
private static final Logger LOGGER = Logger.getLogger(ProcessWizardPage.class);
@@ -62,9 +62,6 @@ public class ProcessWizardPage extends AbstractSearchPage {
})
private WebElement processBox;
- @FindBy(xpath = "//textarea[@ng-model='prettyXml']")
- private WebElement processXml;
-
@FindBy(xpath = "//form[@name='processForm']/div[1]")
private WebElement summaryBox;
@@ -82,15 +79,10 @@ public class ProcessWizardPage extends AbstractSearchPage {
})
private WebElement previousButton;
- @FindBys({
- @FindBy(id = "editXmlButton")
- })
- private WebElement editXmlButton;
-
@FindBy(xpath = "//a[contains(.,'Cancel')]")
private WebElement cancelButton;
- @FindBy(xpath = "//div[contains(@class,'formBoxContainer')]")
+ @FindBy(xpath = "//fieldset[@id='fieldWrapper']")
private WebElement formBox;
public ProcessWizardPage(WebDriver driver) {
@@ -130,11 +122,6 @@ public class ProcessWizardPage extends AbstractSearchPage {
cancelButton.click();
}
- public void clickEditXml(){
- waitForAngularToFinish();
- editXmlButton.click();
- }
-
/*----- Step1 General info ----*/
private WebElement getName() {
@@ -828,20 +815,14 @@ public class ProcessWizardPage extends AbstractSearchPage {
waitForAlert();
}
- /**
- * Creates ProcessMerlin object from xml preview string.
- */
- public ProcessMerlin getProcessMerlinFromProcessXml() throws Exception{
- waitForAngularToFinish();
- return new ProcessMerlin(processXml.getAttribute("value"));
+ @Override
+ public ProcessMerlin getEntityFromXMLPreview() {
+ return new ProcessMerlin(getXMLPreview());
}
- /**
- * Pushes xml string to xml preview.
- */
- public void setProcessXml(String xml) throws Exception{
- processXml.clear();
- processXml.sendKeys(xml);
+ @Override
+ public WebElement getEditXMLButton() {
+ return driver.findElement(By.id("editXmlButton"));
}
/**
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/ExternalFSTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/ExternalFSTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/ExternalFSTest.java
index 0662562..728b797 100644
--- a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/ExternalFSTest.java
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/ExternalFSTest.java
@@ -182,9 +182,9 @@ public class ExternalFSTest extends BaseTestClass{
Path dstPath = new Path(endpoint + testWasbTargetDir + '/' + timePattern);
//check if coordinator exists
+ TimeUtil.sleepSeconds(10);
InstanceUtil.waitTillInstancesAreCreated(clusterOC, feed.toString(), 0);
Assert.assertEquals(OozieUtil.checkIfFeedCoordExist(clusterOC, feed.getName(), "REPLICATION"), 1);
- TimeUtil.sleepSeconds(10);
//replication should start, wait while it ends
InstanceUtil.waitTillInstanceReachState(clusterOC, Util.readEntityName(feed.toString()), 1,
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/FeedReplicationTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/FeedReplicationTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/FeedReplicationTest.java
index 9ac9f24..6728edf 100644
--- a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/FeedReplicationTest.java
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/FeedReplicationTest.java
@@ -18,11 +18,11 @@
package org.apache.falcon.regression;
-import org.apache.falcon.regression.Entities.FeedMerlin;
-import org.apache.falcon.regression.core.bundle.Bundle;
import org.apache.falcon.entity.v0.EntityType;
import org.apache.falcon.entity.v0.feed.ActionType;
import org.apache.falcon.entity.v0.feed.ClusterType;
+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.util.AssertUtil;
import org.apache.falcon.regression.core.util.BundleUtil;
@@ -36,9 +36,11 @@ import org.apache.falcon.regression.testHelper.BaseTestClass;
import org.apache.falcon.resource.InstancesResult;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.security.authentication.client.AuthenticationException;
import org.apache.log4j.Logger;
import org.apache.oozie.client.CoordinatorAction;
import org.apache.oozie.client.OozieClient;
+import org.apache.oozie.client.OozieClientException;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
@@ -51,7 +53,10 @@ import org.testng.annotations.Test;
import javax.xml.bind.JAXBException;
import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* feed replication test.
@@ -383,6 +388,106 @@ public class FeedReplicationTest extends BaseTestClass {
}
/**
+ * Test for https://issues.apache.org/jira/browse/FALCON-668.
+ * Check that new DistCp options are allowed.
+ */
+ @Test
+ public void testNewDistCpOptions()
+ throws URISyntaxException, AuthenticationException, InterruptedException, IOException, JAXBException,
+ OozieClientException {
+ Bundle.submitCluster(bundles[0], bundles[1]);
+ String startTime = TimeUtil.getTimeWrtSystemTime(0);
+ String endTime = TimeUtil.addMinsToTime(startTime, 5);
+ LOGGER.info("Time range between : " + startTime + " and " + endTime);
+ //configure feed
+ String feedName = Util.readEntityName(bundles[0].getDataSets().get(0));
+ FeedMerlin feedElement = bundles[0].getFeedElement(feedName);
+ bundles[0].writeFeedElement(feedElement, feedName);
+ FeedMerlin feed = new FeedMerlin(bundles[0].getDataSets().get(0));
+ feed.setFilePath(feedDataLocation);
+ //erase all clusters from feed definition
+ feed.clearFeedClusters();
+ //set cluster1 as source
+ feed.addFeedCluster(
+ new FeedMerlin.FeedClusterBuilder(Util.readEntityName(bundles[0].getClusters().get(0)))
+ .withRetention("days(1000000)", ActionType.DELETE)
+ .withValidity(startTime, endTime)
+ .withClusterType(ClusterType.SOURCE)
+ .build());
+ //set cluster2 as target
+ feed.addFeedCluster(
+ new FeedMerlin.FeedClusterBuilder(Util.readEntityName(bundles[1].getClusters().get(0)))
+ .withRetention("days(1000000)", ActionType.DELETE)
+ .withValidity(startTime, endTime)
+ .withClusterType(ClusterType.TARGET)
+ .withDataLocation(targetDataLocation)
+ .build());
+
+ //add custom properties to feed
+ HashMap<String, String> propMap = new HashMap<>();
+ propMap.put("overwrite", "true");
+ propMap.put("ignoreErrors", "false");
+ propMap.put("skipChecksum", "false");
+ propMap.put("removeDeletedFiles", "true");
+ propMap.put("preserveBlockSize", "true");
+ propMap.put("preserveReplicationNumber", "true");
+ propMap.put("preservePermission", "true");
+ for (Map.Entry<String, String> entry : propMap.entrySet()) {
+ feed.withProperty(entry.getKey(), entry.getValue());
+ }
+ //add custom property which shouldn't be passed to workflow
+ HashMap<String, String> unsupportedPropMap = new HashMap<>();
+ unsupportedPropMap.put("myCustomProperty", "true");
+ feed.withProperty("myCustomProperty", "true");
+
+ //upload necessary data to source
+ DateTime date = new DateTime(startTime, DateTimeZone.UTC);
+ DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy'/'MM'/'dd'/'HH'/'mm'");
+ String timePattern = fmt.print(date);
+ String sourceLocation = sourcePath + "/" + timePattern + "/";
+ HadoopUtil.recreateDir(cluster1FS, sourceLocation);
+ HadoopUtil.copyDataToFolder(cluster1FS, sourceLocation, OSUtil.concat(OSUtil.NORMAL_INPUT, "dataFile.xml"));
+ HadoopUtil.copyDataToFolder(cluster1FS, sourceLocation, OSUtil.concat(OSUtil.NORMAL_INPUT, "dataFile1.txt"));
+
+ //copy 2 files to target to check if they will be deleted because of removeDeletedFiles property
+ String targetLocation = targetPath + "/" + timePattern + "/";
+ cluster2FS.copyFromLocalFile(new Path(OSUtil.concat(OSUtil.NORMAL_INPUT, "dataFile3.txt")),
+ new Path(targetLocation + "dataFile3.txt"));
+
+ //submit and schedule feed
+ LOGGER.info("Feed : " + Util.prettyPrintXml(feed.toString()));
+ AssertUtil.assertSucceeded(prism.getFeedHelper().submitAndSchedule(feed.toString()));
+
+ //check while instance is got created
+ InstanceUtil.waitTillInstancesAreCreated(cluster2OC, feed.toString(), 0);
+
+ //check if coordinator exists and replication starts
+ Assert.assertEquals(OozieUtil.checkIfFeedCoordExist(cluster2OC, feed.getName(), "REPLICATION"), 1);
+ InstanceUtil.waitTillInstanceReachState(cluster2OC, feed.getName(), 1,
+ CoordinatorAction.Status.RUNNING, EntityType.FEED);
+
+ //check that properties were passed to workflow definition
+ String bundleId = OozieUtil.getLatestBundleID(cluster2OC, feedName, EntityType.FEED);
+ String coordId = OozieUtil.getReplicationCoordID(bundleId, cluster2.getFeedHelper()).get(0);
+ CoordinatorAction coordinatorAction = cluster2OC.getCoordJobInfo(coordId).getActions().get(0);
+ String wfDefinition = cluster2OC.getJobDefinition(coordinatorAction.getExternalId());
+ LOGGER.info(String.format("Definition of coordinator job action %s : \n %s \n",
+ coordinatorAction.getExternalId(), Util.prettyPrintXml(wfDefinition)));
+ Assert.assertTrue(OozieUtil.propsArePresentInWorkflow(wfDefinition, "replication", propMap),
+ "New distCp supported properties should be passed to replication args list.");
+ Assert.assertFalse(OozieUtil.propsArePresentInWorkflow(wfDefinition, "replication", unsupportedPropMap),
+ "Unsupported properties shouldn't be passed to replication args list.");
+
+ //check that replication succeeds
+ InstanceUtil.waitTillInstanceReachState(cluster2OC, feed.getName(), 1,
+ CoordinatorAction.Status.SUCCEEDED, EntityType.FEED);
+
+ List<Path> finalFiles = HadoopUtil.getAllFilesRecursivelyHDFS(cluster2FS, new Path(targetPath));
+ Assert.assertEquals(finalFiles.size(), 2, "Only replicated files should be present on target "
+ + "because of 'removeDeletedFiles' distCp property.");
+ }
+
+ /**
* Test demonstrates failure pf replication of stored data from one source cluster to one target cluster.
* When replication job fails test checks if failed logs are present in staging directory or not.
*/
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/ProcessInstanceStatusTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/ProcessInstanceStatusTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/ProcessInstanceStatusTest.java
index 7f1e445..6493133 100644
--- a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/ProcessInstanceStatusTest.java
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/ProcessInstanceStatusTest.java
@@ -434,6 +434,45 @@ public class ProcessInstanceStatusTest extends BaseTestClass {
InstanceUtil.validateFailedInstances(r, 3);
}
+ /**
+ * Check that default end time param value is now.
+ */
+ @Test
+ public void testDefaultEndTimeParam()
+ throws OozieClientException, IOException, InterruptedException, AuthenticationException, URISyntaxException,
+ JAXBException {
+ //set validity to have 12 instances
+ String start = TimeUtil.getTimeWrtSystemTime(-60);
+ String end = TimeUtil.getTimeWrtSystemTime(0);
+ bundles[0].setProcessValidity(start, end);
+ bundles[0].setProcessPeriodicity(5, TimeUnit.minutes);
+ bundles[0].setProcessConcurrency(3);
+ bundles[0].submitFeedsScheduleProcess(prism);
+ InstanceUtil.waitTillInstancesAreCreated(clusterOC, bundles[0].getProcessData(), 0);
+ //make first 3 instances running
+ OozieUtil.createMissingDependencies(cluster, EntityType.PROCESS, processName, 0, 0);
+ OozieUtil.createMissingDependencies(cluster, EntityType.PROCESS, processName, 0, 1);
+ OozieUtil.createMissingDependencies(cluster, EntityType.PROCESS, processName, 0, 2);
+ InstanceUtil.waitTillInstanceReachState(clusterOC, processName, 3, Status.RUNNING,
+ EntityType.PROCESS);
+ //check instances status with end, expected first 10 instances
+ InstancesResult r = prism.getProcessHelper().getProcessInstanceStatus(processName,
+ "?start=" + start + "&end=" + TimeUtil.addMinsToTime(end, -11));
+ InstanceUtil.validateResponse(r, 10, 3, 0, 7, 0);
+ //request the same but without end, expected to have the latest 10 instances
+ r = prism.getProcessHelper().getProcessInstanceStatus(processName,
+ "?start=" + start);
+ InstanceUtil.validateResponse(r, 10, 1, 0, 9, 0);
+ //the same with numResults which includes/excludes all running instances
+ r = prism.getProcessHelper().getProcessInstanceStatus(processName,
+ "?start=" + start + "&end=" + TimeUtil.addMinsToTime(end, -16) + "&numResults=9");
+ InstanceUtil.validateResponse(r, 9, 3, 0, 6, 0);
+ //expected end is set to now, thus getting last 9 instances
+ r = prism.getProcessHelper().getProcessInstanceStatus(processName,
+ "?start=" + start + "&numResults=9");
+ InstanceUtil.validateResponse(r, 9, 0, 0, 9, 0);
+ }
+
/*
* Function to match the workflows obtained from instance status and oozie.
*/
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/ProcessUpdateTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/ProcessUpdateTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/ProcessUpdateTest.java
new file mode 100644
index 0000000..efbb503
--- /dev/null
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/ProcessUpdateTest.java
@@ -0,0 +1,112 @@
+/**
+ * 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.EntityType;
+import org.apache.falcon.entity.v0.Frequency;
+import org.apache.falcon.entity.v0.process.LateInput;
+import org.apache.falcon.entity.v0.process.LateProcess;
+import org.apache.falcon.entity.v0.process.PolicyType;
+import org.apache.falcon.regression.Entities.ProcessMerlin;
+import org.apache.falcon.regression.core.bundle.Bundle;
+import org.apache.falcon.regression.core.helpers.ColoHelper;
+import org.apache.falcon.regression.core.util.AssertUtil;
+import org.apache.falcon.regression.core.util.BundleUtil;
+import org.apache.falcon.regression.core.util.InstanceUtil;
+import org.apache.falcon.regression.core.util.OSUtil;
+import org.apache.falcon.regression.core.util.OozieUtil;
+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.apache.oozie.client.OozieClient;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * Tests related to update feature.
+ */
+@Test(groups = "embedded")
+public class ProcessUpdateTest extends BaseTestClass {
+
+ private ColoHelper cluster = servers.get(0);
+ private OozieClient clusterOC = serverOC.get(0);
+ private String baseTestHDFSDir = cleanAndGetTestDir();
+ private String aggregateWorkflowDir = baseTestHDFSDir + "/aggregator";
+ private String feedInputPath = baseTestHDFSDir + "/input" + MINUTE_DATE_PATTERN;
+ private String feedOutputPath = baseTestHDFSDir + "/output-data" + MINUTE_DATE_PATTERN;
+ private static final Logger LOGGER = Logger.getLogger(ProcessUpdateTest.class);
+
+ @BeforeClass(alwaysRun = true)
+ public void uploadWorkflow() throws Exception {
+ uploadDirToClusters(aggregateWorkflowDir, OSUtil.RESOURCES_OOZIE);
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp() throws Exception {
+ Bundle bundle = BundleUtil.readELBundle();
+ bundles[0] = new Bundle(bundle, servers.get(0));
+ bundles[0].generateUniqueBundle(this);
+ bundles[0].setProcessWorkflow(aggregateWorkflowDir);
+ bundles[0].setInputFeedDataPath(feedInputPath);
+ bundles[0].setOutputFeedLocationData(feedOutputPath);
+ }
+
+ /**
+ * Test for https://issues.apache.org/jira/browse/FALCON-99.
+ * Scenario: schedule a process which doesn't have late data handling and then update it to have it.
+ * Check that new coordinator was created.
+ */
+ @Test
+ public void updateProcessWithLateData() throws Exception {
+ String start = TimeUtil.getTimeWrtSystemTime(-60);
+ String end = TimeUtil.getTimeWrtSystemTime(10);
+ bundles[0].submitAndScheduleAllFeeds();
+ ProcessMerlin process = bundles[0].getProcessObject();
+ process.setValidity(start, end);
+ process.setLateProcess(null);
+ cluster.getProcessHelper().submitAndSchedule(process.toString());
+ InstanceUtil.waitTillInstancesAreCreated(clusterOC, process.toString(), 0);
+ String bundleId = OozieUtil.getLatestBundleID(clusterOC, process.getName(), EntityType.PROCESS);
+
+ //update process to have late data handling
+ LateProcess lateProcess = new LateProcess();
+ lateProcess.setDelay(new Frequency("hours(1)"));
+ lateProcess.setPolicy(PolicyType.EXP_BACKOFF);
+ LateInput lateInput = new LateInput();
+ lateInput.setInput("inputData");
+ lateInput.setWorkflowPath(aggregateWorkflowDir);
+ lateProcess.getLateInputs().add(lateInput);
+ process.setLateProcess(lateProcess);
+ LOGGER.info("Updated process xml: " + Util.prettyPrintXml(process.toString()));
+ AssertUtil.assertSucceeded(cluster.getProcessHelper().update(process.toString(), process.toString()));
+
+ //check that new coordinator was created
+ String newBundleId = OozieUtil.getLatestBundleID(clusterOC, process.getName(), EntityType.PROCESS);
+ Assert.assertNotEquals(bundleId, newBundleId, "New Bundle should be created.");
+ }
+
+ @AfterMethod(alwaysRun = true)
+ public void tearDown() {
+ removeTestClassEntities();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/TestngListener.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/TestngListener.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/TestngListener.java
index 9ea8471..ca6ee88 100644
--- a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/TestngListener.java
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/TestngListener.java
@@ -77,7 +77,7 @@ public class TestngListener implements ITestListener, IExecutionListener {
LOGGER.info("Dumping of falcon store failed: " + e);
}
LOGGER.info(
- String.format("Testing going to end for: %s.%s(%s) %s", result.getTestClass().getName(),
+ String.format("Testing going to end for: %s.%s(%s) ----- Status: %s", result.getTestClass().getName(),
result.getName(), Arrays.toString(result.getParameters()), outcome));
NDC.pop();
LOGGER.info(hr);
[2/3] falcon git commit: Add ProcessUpdateTest,
PipelineInstanceDependencyTest and other tests and test fixes.
Contributed by Raghav Gautam and Paul Isaychuk
Posted by pi...@apache.org.
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/hive/dr/HiveDRTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/hive/dr/HiveDRTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/hive/dr/HiveDRTest.java
index 1c788a3..bfc0d66 100644
--- a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/hive/dr/HiveDRTest.java
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/hive/dr/HiveDRTest.java
@@ -30,6 +30,7 @@ import org.apache.falcon.regression.core.supportClasses.NotifyingAssert;
import org.apache.falcon.regression.core.util.BundleUtil;
import org.apache.falcon.regression.core.util.HiveAssert;
import org.apache.falcon.regression.core.util.InstanceUtil;
+import org.apache.falcon.regression.core.util.MatrixUtil;
import org.apache.falcon.regression.core.util.OozieUtil;
import org.apache.falcon.regression.core.util.TimeUtil;
import org.apache.falcon.regression.testHelper.BaseTestClass;
@@ -42,14 +43,12 @@ import org.apache.oozie.client.CoordinatorJob;
import org.apache.oozie.client.OozieClient;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.testng.asserts.SoftAssert;
import java.io.IOException;
import java.sql.Connection;
-import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
@@ -76,6 +75,7 @@ public class HiveDRTest extends BaseTestClass {
private final FileSystem clusterFS3 = serverFS.get(2);
private final OozieClient clusterOC = serverOC.get(0);
private final OozieClient clusterOC2 = serverOC.get(1);
+ private final OozieClient clusterOC3 = serverOC.get(2);
private final String baseTestHDFSDir = cleanAndGetTestDir() + "/HiveDR/";
private HCatClient clusterHC;
private HCatClient clusterHC2;
@@ -83,8 +83,12 @@ public class HiveDRTest extends BaseTestClass {
private Connection connection;
private Connection connection2;
- @BeforeMethod(alwaysRun = true)
- public void setUp() throws Exception {
+ @DataProvider
+ public Object[][] getRecipeLocation() {
+ return MatrixUtil.crossProduct(RecipeExecLocation.values());
+ }
+
+ private void setUp(RecipeExecLocation recipeExecLocation) throws Exception {
clusterHC = cluster.getClusterHelper().getHCatClient();
clusterHC2 = cluster2.getClusterHelper().getHCatClient();
bundles[0] = new Bundle(BundleUtil.readHCatBundle(), cluster);
@@ -93,21 +97,17 @@ public class HiveDRTest extends BaseTestClass {
bundles[1].generateUniqueBundle(this);
final ClusterMerlin srcCluster = bundles[0].getClusterElement();
final ClusterMerlin tgtCluster = bundles[1].getClusterElement();
- Bundle.submitCluster(bundles[0]);
-
+ String recipeDir = "HiveDrRecipe";
if (MerlinConstants.IS_SECURE) {
- recipeMerlin = RecipeMerlin.readFromDir("HiveDrSecureRecipe",
- FalconCLI.RecipeOperation.HIVE_DISASTER_RECOVERY)
- .withRecipeCluster(srcCluster);
- } else {
- recipeMerlin = RecipeMerlin.readFromDir("HiveDrRecipe",
- FalconCLI.RecipeOperation.HIVE_DISASTER_RECOVERY)
- .withRecipeCluster(srcCluster);
+ recipeDir = "HiveDrSecureRecipe";
}
+ Bundle.submitCluster(recipeExecLocation.getRecipeBundle(bundles[0], bundles[1]));
+ recipeMerlin = RecipeMerlin.readFromDir(recipeDir, FalconCLI.RecipeOperation.HIVE_DISASTER_RECOVERY)
+ .withRecipeCluster(recipeExecLocation.getRecipeCluster(srcCluster, tgtCluster));
recipeMerlin.withSourceCluster(srcCluster)
.withTargetCluster(tgtCluster)
.withFrequency(new Frequency("5", Frequency.TimeUnit.minutes))
- .withValidity(TimeUtil.getTimeWrtSystemTime(-5), TimeUtil.getTimeWrtSystemTime(5));
+ .withValidity(TimeUtil.getTimeWrtSystemTime(-5), TimeUtil.getTimeWrtSystemTime(15));
recipeMerlin.setUniqueName(this.getClass().getSimpleName());
connection = cluster.getClusterHelper().getHiveJdbcConnection();
@@ -121,8 +121,9 @@ public class HiveDRTest extends BaseTestClass {
runSql(connection2, "use hdr_sdb1");
}
- @Test
- public void drPartition() throws Exception {
+ @Test(dataProvider = "getRecipeLocation")
+ public void drPartition(final RecipeExecLocation recipeExecLocation) throws Exception {
+ setUp(recipeExecLocation);
final String tblName = "partitionDR";
recipeMerlin.withSourceDb(DB_NAME).withSourceTable(tblName);
final List<String> command = recipeMerlin.getSubmissionCommand();
@@ -157,8 +158,8 @@ public class HiveDRTest extends BaseTestClass {
Assert.assertEquals(Bundle.runFalconCLI(command), 0, "Recipe submission failed.");
- InstanceUtil.waitTillInstanceReachState(clusterOC, recipeMerlin.getName(), 1,
- CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
+ InstanceUtil.waitTillInstanceReachState(recipeExecLocation.getRecipeOC(clusterOC, clusterOC2),
+ recipeMerlin.getName(), 1, CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
HiveAssert.assertTableEqual(cluster, clusterHC.getTable(DB_NAME, tblName),
cluster2, clusterHC2.getTable(DB_NAME, tblName), new NotifyingAssert(true)
@@ -167,6 +168,8 @@ public class HiveDRTest extends BaseTestClass {
@Test
public void drInsertOverwritePartition() throws Exception {
+ final RecipeExecLocation recipeExecLocation = RecipeExecLocation.SourceCluster;
+ setUp(recipeExecLocation);
final String tblName = "drInsertOverwritePartition";
final String hlpTblName = "drInsertOverwritePartitionHelperTbl";
recipeMerlin.withSourceDb(DB_NAME).withSourceTable(tblName);
@@ -200,8 +203,8 @@ public class HiveDRTest extends BaseTestClass {
Assert.assertEquals(Bundle.runFalconCLI(command), 0, "Recipe submission failed.");
- InstanceUtil.waitTillInstanceReachState(clusterOC, recipeMerlin.getName(), 1,
- CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
+ InstanceUtil.waitTillInstanceReachState(recipeExecLocation.getRecipeOC(clusterOC, clusterOC2),
+ recipeMerlin.getName(), 1, CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
HiveAssert.assertTableEqual(cluster, clusterHC.getTable(DB_NAME, tblName),
cluster2, clusterHC2.getTable(DB_NAME, tblName), new NotifyingAssert(true)
@@ -210,6 +213,8 @@ public class HiveDRTest extends BaseTestClass {
@Test
public void drTwoTablesOneRequest() throws Exception {
+ final RecipeExecLocation recipeExecLocation = RecipeExecLocation.TargetCluster;
+ setUp(recipeExecLocation);
final String tblName = "firstTableDR";
final String tbl2Name = "secondTableDR";
recipeMerlin.withSourceDb(DB_NAME).withSourceTable(tblName + ',' + tbl2Name);
@@ -232,8 +237,8 @@ public class HiveDRTest extends BaseTestClass {
Assert.assertEquals(Bundle.runFalconCLI(command), 0, "Recipe submission failed.");
- InstanceUtil.waitTillInstanceReachState(clusterOC, recipeMerlin.getName(), 1,
- CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
+ InstanceUtil.waitTillInstanceReachState(recipeExecLocation.getRecipeOC(clusterOC, clusterOC2),
+ recipeMerlin.getName(), 1, CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
final NotifyingAssert anAssert = new NotifyingAssert(true);
HiveAssert.assertTableEqual(cluster, clusterHC.getTable(DB_NAME, tblName),
@@ -246,6 +251,8 @@ public class HiveDRTest extends BaseTestClass {
@Test
public void drSerDeWithProperties() throws Exception {
+ final RecipeExecLocation recipeExecLocation = RecipeExecLocation.SourceCluster;
+ setUp(recipeExecLocation);
final String tblName = "serdeTable";
recipeMerlin.withSourceDb(DB_NAME).withSourceTable(tblName);
final List<String> command = recipeMerlin.getSubmissionCommand();
@@ -265,8 +272,8 @@ public class HiveDRTest extends BaseTestClass {
Assert.assertEquals(Bundle.runFalconCLI(command), 0, "Recipe submission failed.");
- InstanceUtil.waitTillInstanceReachState(clusterOC, recipeMerlin.getName(), 1,
- CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
+ InstanceUtil.waitTillInstanceReachState(recipeExecLocation.getRecipeOC(clusterOC, clusterOC2),
+ recipeMerlin.getName(), 1, CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
HiveAssert.assertTableEqual(cluster, clusterHC.getTable(DB_NAME, tblName),
cluster2, clusterHC2.getTable(DB_NAME, tblName), new NotifyingAssert(true)
@@ -276,6 +283,8 @@ public class HiveDRTest extends BaseTestClass {
@Test
public void drChangeColumn() throws Exception {
+ final RecipeExecLocation recipeExecLocation = RecipeExecLocation.SourceCluster;
+ setUp(recipeExecLocation);
final String tblName = "tableForColumnChange";
recipeMerlin.withSourceDb(DB_NAME).withSourceTable(tblName);
final List<String> command1 = recipeMerlin.getSubmissionCommand();
@@ -289,10 +298,8 @@ public class HiveDRTest extends BaseTestClass {
runSql(connection,
"ALTER TABLE " + tblName + " CHANGE id id STRING COMMENT 'some_comment'");
-
- InstanceUtil.waitTillInstanceReachState(clusterOC, recipe1Name, 1,
- CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
-
+ InstanceUtil.waitTillInstanceReachState(recipeExecLocation.getRecipeOC(clusterOC, clusterOC2),
+ recipe1Name, 1, CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
HiveAssert.assertTableEqual(cluster, clusterHC.getTable(DB_NAME, tblName),
cluster2, clusterHC2.getTable(DB_NAME, tblName), new NotifyingAssert(true)
@@ -302,6 +309,8 @@ public class HiveDRTest extends BaseTestClass {
@Test
public void drTwoDstTablesTwoRequests() throws Exception {
+ final RecipeExecLocation recipeExecLocation = RecipeExecLocation.TargetCluster;
+ setUp(recipeExecLocation);
final HCatClient clusterHC3 = cluster3.getClusterHelper().getHCatClient();
final Connection connection3 = cluster3.getClusterHelper().getHiveJdbcConnection();
runSql(connection3, "drop database if exists hdr_sdb1 cascade");
@@ -313,9 +322,12 @@ public class HiveDRTest extends BaseTestClass {
final String recipe1Name = recipeMerlin.getName();
final List<String> command1 = recipeMerlin.getSubmissionCommand();
- final Bundle bundle = BundleUtil.readHCatBundle();
- bundle.generateUniqueBundle(this);
- recipeMerlin.withTargetCluster(new Bundle(bundle, cluster3).getClusterElement());
+ final Bundle bundle3 = new Bundle(BundleUtil.readHCatBundle(), cluster3);
+ bundle3.generateUniqueBundle(this);
+ bundle3.submitClusters(prism);
+ recipeMerlin.withTargetCluster(bundle3.getClusterElement())
+ .withRecipeCluster(recipeExecLocation.getRecipeCluster(
+ bundles[0].getClusterElement(), bundle3.getClusterElement()));
recipeMerlin.setUniqueName(this.getClass().getSimpleName());
final List<String> command2 = recipeMerlin.getSubmissionCommand();
@@ -334,10 +346,10 @@ public class HiveDRTest extends BaseTestClass {
Assert.assertEquals(Bundle.runFalconCLI(command2), 0, "Recipe submission failed.");
- InstanceUtil.waitTillInstanceReachState(clusterOC, recipe1Name, 1,
- CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
- InstanceUtil.waitTillInstanceReachState(clusterOC, recipe2Name, 1,
- CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
+ InstanceUtil.waitTillInstanceReachState(recipeExecLocation.getRecipeOC(clusterOC, clusterOC2),
+ recipe1Name, 1, CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
+ InstanceUtil.waitTillInstanceReachState(recipeExecLocation.getRecipeOC(clusterOC, clusterOC3),
+ recipe2Name, 1, CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
final NotifyingAssert anAssert = new NotifyingAssert(true);
HiveAssert.assertTableEqual(cluster, clusterHC.getTable(DB_NAME, tblName),
@@ -349,6 +361,8 @@ public class HiveDRTest extends BaseTestClass {
@Test
public void drExternalToNonExternal() throws Exception {
+ final RecipeExecLocation recipeExecLocation = RecipeExecLocation.SourceCluster;
+ setUp(recipeExecLocation);
final String tblName = "externalToNonExternal";
recipeMerlin.withSourceDb(DB_NAME).withSourceTable(tblName);
final List<String> command = recipeMerlin.getSubmissionCommand();
@@ -362,8 +376,8 @@ public class HiveDRTest extends BaseTestClass {
Assert.assertEquals(Bundle.runFalconCLI(command), 0, "Recipe submission failed.");
- InstanceUtil.waitTillInstanceReachState(clusterOC, recipeMerlin.getName(), 1,
- CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
+ InstanceUtil.waitTillInstanceReachState(recipeExecLocation.getRecipeOC(clusterOC, clusterOC2),
+ recipeMerlin.getName(), 1, CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
final NotifyingAssert anAssert = new NotifyingAssert(true);
HiveAssert.assertTableEqual(cluster, clusterHC.getTable(DB_NAME, tblName),
@@ -379,6 +393,8 @@ public class HiveDRTest extends BaseTestClass {
@Test
public void drExtPartitionedToNonExtPartitioned() throws Exception {
+ final RecipeExecLocation recipeExecLocation = RecipeExecLocation.SourceCluster;
+ setUp(recipeExecLocation);
final String tblName = "extPartitionedToNonExtPartitioned";
recipeMerlin.withSourceDb(DB_NAME).withSourceTable(tblName);
final List<String> command = recipeMerlin.getSubmissionCommand();
@@ -408,8 +424,8 @@ public class HiveDRTest extends BaseTestClass {
runSql(connection,
"alter table " + tblName + " change column data data_new string");
- InstanceUtil.waitTillInstanceReachState(clusterOC, recipeMerlin.getName(), 1,
- CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
+ InstanceUtil.waitTillInstanceReachState(recipeExecLocation.getRecipeOC(clusterOC, clusterOC2),
+ recipeMerlin.getName(), 1, CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
HiveAssert.assertTableEqual(cluster, clusterHC.getTable(DB_NAME, tblName),
cluster2, clusterHC2.getTable(DB_NAME, tblName), anAssert, false);
@@ -428,6 +444,8 @@ public class HiveDRTest extends BaseTestClass {
*/
@Test
public void drChangeCommentAndPropertyTest() throws Exception {
+ final RecipeExecLocation recipeExecLocation = RecipeExecLocation.SourceCluster;
+ setUp(recipeExecLocation);
final String tblName = "myTable";
recipeMerlin.withSourceDb(DB_NAME).withSourceTable(tblName);
final List<String> command = recipeMerlin.getSubmissionCommand();
@@ -458,8 +476,8 @@ public class HiveDRTest extends BaseTestClass {
Assert.assertEquals(Bundle.runFalconCLI(command), 0, "Recipe submission failed.");
- InstanceUtil.waitTillInstanceReachState(clusterOC, recipeMerlin.getName(), 1,
- CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
+ InstanceUtil.waitTillInstanceReachState(recipeExecLocation.getRecipeOC(clusterOC, clusterOC2),
+ recipeMerlin.getName(), 1, CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
HiveAssert.assertTableEqual(cluster, clusterHC.getTable(DB_NAME, tblName),
cluster2, clusterHC2.getTable(DB_NAME, tblName), new NotifyingAssert(true)
@@ -468,6 +486,7 @@ public class HiveDRTest extends BaseTestClass {
@Test
public void dataGeneration() throws Exception {
+ setUp(RecipeExecLocation.SourceCluster);
runSql(connection, "use hdr_sdb1");
createVanillaTable(connection, "store_sales");
createSerDeTable(connection);
@@ -498,6 +517,7 @@ public class HiveDRTest extends BaseTestClass {
@Test(enabled = false)
public void assertionTest() throws Exception {
+ setUp(RecipeExecLocation.SourceCluster);
final SoftAssert anAssert = new SoftAssert();
HiveAssert.assertTableEqual(
cluster, clusterHC.getTable("default", "hcatsmoke10546"),
@@ -515,7 +535,8 @@ public class HiveDRTest extends BaseTestClass {
* @throws IOException
*/
@Test
- public void dynamicPartitionsTest() throws SQLException, IOException {
+ public void dynamicPartitionsTest() throws Exception {
+ setUp(RecipeExecLocation.SourceCluster);
//create table with static partitions on first cluster
createPartitionedTable(connection, false);
@@ -535,6 +556,8 @@ public class HiveDRTest extends BaseTestClass {
*/
@Test
public void drInsertDropReplaceDynamicPartition() throws Exception {
+ final RecipeExecLocation recipeExecLocation = RecipeExecLocation.SourceCluster;
+ setUp(recipeExecLocation);
final String tblName = "dynamicPartitionDR";
recipeMerlin.withSourceDb(DB_NAME).withSourceTable(tblName);
final List<String> command = recipeMerlin.getSubmissionCommand();
@@ -577,8 +600,8 @@ public class HiveDRTest extends BaseTestClass {
Assert.assertEquals(Bundle.runFalconCLI(command), 0, "Recipe submission failed.");
- InstanceUtil.waitTillInstanceReachState(clusterOC, recipeMerlin.getName(), 1,
- CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
+ InstanceUtil.waitTillInstanceReachState(recipeExecLocation.getRecipeOC(clusterOC, clusterOC2),
+ recipeMerlin.getName(), 1, CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
HiveAssert.assertTableEqual(cluster, clusterHC.getTable(DB_NAME, tblName),
cluster2, clusterHC2.getTable(DB_NAME, tblName), new NotifyingAssert(true)
@@ -592,6 +615,8 @@ public class HiveDRTest extends BaseTestClass {
*/
@Test
public void drInsertOverwriteDynamicPartition() throws Exception {
+ final RecipeExecLocation recipeExecLocation = RecipeExecLocation.SourceCluster;
+ setUp(recipeExecLocation);
final String tblName = "drInsertOverwritePartition";
final String hlpTblName = "drInsertOverwritePartitionHelperTbl";
recipeMerlin.withSourceDb(DB_NAME).withSourceTable(tblName);
@@ -637,8 +662,8 @@ public class HiveDRTest extends BaseTestClass {
Assert.assertEquals(Bundle.runFalconCLI(command), 0, "Recipe submission failed.");
- InstanceUtil.waitTillInstanceReachState(clusterOC, recipeMerlin.getName(), 1,
- CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
+ InstanceUtil.waitTillInstanceReachState(recipeExecLocation.getRecipeOC(clusterOC, clusterOC2),
+ recipeMerlin.getName(), 1, CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
HiveAssert.assertTableEqual(cluster, clusterHC.getTable(DB_NAME, tblName),
cluster2, clusterHC2.getTable(DB_NAME, tblName), new NotifyingAssert(true)
@@ -651,6 +676,7 @@ public class HiveDRTest extends BaseTestClass {
*/
@Test(dataProvider = "frequencyGenerator")
public void differentRecipeFrequenciesTest(String frequency) throws Exception {
+ setUp(RecipeExecLocation.SourceCluster);
LOGGER.info("Testing with frequency: " + frequency);
String tblName = "myTable";
recipeMerlin.withSourceDb(DB_NAME).withSourceTable(tblName)
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/hive/dr/HiveDbDRTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/hive/dr/HiveDbDRTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/hive/dr/HiveDbDRTest.java
index a64bd6d..5efd69f 100644
--- a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/hive/dr/HiveDbDRTest.java
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/hive/dr/HiveDbDRTest.java
@@ -32,6 +32,7 @@ import org.apache.falcon.regression.core.util.Config;
import org.apache.falcon.regression.core.util.HadoopUtil;
import org.apache.falcon.regression.core.util.HiveAssert;
import org.apache.falcon.regression.core.util.InstanceUtil;
+import org.apache.falcon.regression.core.util.MatrixUtil;
import org.apache.falcon.regression.core.util.TimeUtil;
import org.apache.falcon.regression.testHelper.BaseTestClass;
import org.apache.hadoop.fs.FileSystem;
@@ -43,7 +44,6 @@ import org.apache.oozie.client.CoordinatorAction;
import org.apache.oozie.client.OozieClient;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@@ -67,14 +67,19 @@ public class HiveDbDRTest extends BaseTestClass {
private final FileSystem clusterFS = serverFS.get(0);
private final FileSystem clusterFS2 = serverFS.get(1);
private final OozieClient clusterOC = serverOC.get(0);
+ private final OozieClient clusterOC2 = serverOC.get(1);
private HCatClient clusterHC;
private HCatClient clusterHC2;
private RecipeMerlin recipeMerlin;
private Connection connection;
private Connection connection2;
- @BeforeMethod(alwaysRun = true)
- public void setUp() throws Exception {
+ @DataProvider
+ public Object[][] getRecipeLocation() {
+ return MatrixUtil.crossProduct(RecipeExecLocation.values());
+ }
+
+ private void setUp(RecipeExecLocation recipeExecLocation) throws Exception {
clusterHC = cluster.getClusterHelper().getHCatClient();
clusterHC2 = cluster2.getClusterHelper().getHCatClient();
bundles[0] = new Bundle(BundleUtil.readHCatBundle(), cluster);
@@ -83,17 +88,14 @@ public class HiveDbDRTest extends BaseTestClass {
bundles[1].generateUniqueBundle(this);
final ClusterMerlin srcCluster = bundles[0].getClusterElement();
final ClusterMerlin tgtCluster = bundles[1].getClusterElement();
- Bundle.submitCluster(bundles[0]);
+ Bundle.submitCluster(recipeExecLocation.getRecipeBundle(bundles[0], bundles[1]));
+ String recipeDir = "HiveDrRecipe";
if (MerlinConstants.IS_SECURE) {
- recipeMerlin = RecipeMerlin.readFromDir("HiveDrSecureRecipe",
- FalconCLI.RecipeOperation.HIVE_DISASTER_RECOVERY)
- .withRecipeCluster(srcCluster);
- } else {
- recipeMerlin = RecipeMerlin.readFromDir("HiveDrRecipe",
- FalconCLI.RecipeOperation.HIVE_DISASTER_RECOVERY)
- .withRecipeCluster(srcCluster);
+ recipeDir = "HiveDrSecureRecipe";
}
+ recipeMerlin = RecipeMerlin.readFromDir(recipeDir, FalconCLI.RecipeOperation.HIVE_DISASTER_RECOVERY)
+ .withRecipeCluster(recipeExecLocation.getRecipeCluster(srcCluster, tgtCluster));
recipeMerlin.withSourceCluster(srcCluster)
.withTargetCluster(tgtCluster)
.withFrequency(new Frequency("5", Frequency.TimeUnit.minutes))
@@ -111,8 +113,9 @@ public class HiveDbDRTest extends BaseTestClass {
runSql(conn, "use " + dbName);
}
- @Test
- public void drDbDropDb() throws Exception {
+ @Test(dataProvider = "getRecipeLocation")
+ public void drDbDropDb(final RecipeExecLocation recipeExecLocation) throws Exception {
+ setUp(recipeExecLocation);
final String dbName = "drDbDropDb";
setUpDb(dbName, connection);
setUpDb(dbName, connection2);
@@ -123,8 +126,8 @@ public class HiveDbDRTest extends BaseTestClass {
runSql(connection, "drop database " + dbName);
- InstanceUtil.waitTillInstanceReachState(clusterOC, recipeMerlin.getName(), 1,
- CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
+ InstanceUtil.waitTillInstanceReachState(recipeExecLocation.getRecipeOC(clusterOC, clusterOC2),
+ recipeMerlin.getName(), 1, CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
final List<String> dstDbs = runSql(connection2, "show databases");
Assert.assertFalse(dstDbs.contains(dbName), "dstDbs = " + dstDbs + " was not expected to "
@@ -134,6 +137,8 @@ public class HiveDbDRTest extends BaseTestClass {
@Test(dataProvider = "isDBReplication")
public void drDbFailPass(Boolean isDBReplication) throws Exception {
+ final RecipeExecLocation recipeExecLocation = RecipeExecLocation.SourceCluster;
+ setUp(recipeExecLocation);
final String dbName = "drDbFailPass";
final String tblName = "vanillaTable";
final String hiveWarehouseLocation = Config.getProperty("hive.warehouse.location", "/apps/hive/warehouse/");
@@ -153,15 +158,15 @@ public class HiveDbDRTest extends BaseTestClass {
LOGGER.info("Setting " + clusterFS2.getUri() + dbPath + " to : " + noReadWritePerm);
clusterFS2.setPermission(new Path(dbPath), FsPermission.valueOf(noReadWritePerm));
- InstanceUtil.waitTillInstanceReachState(clusterOC, recipeMerlin.getName(), 1,
- CoordinatorAction.Status.KILLED, EntityType.PROCESS);
+ InstanceUtil.waitTillInstanceReachState(recipeExecLocation.getRecipeOC(clusterOC, clusterOC2),
+ recipeMerlin.getName(), 1, CoordinatorAction.Status.KILLED, EntityType.PROCESS);
final String readWritePerm = "drwxr-xr-x";
LOGGER.info("Setting " + clusterFS2.getUri() + dbPath + " to : " + readWritePerm);
clusterFS2.setPermission(new Path(dbPath), FsPermission.valueOf(readWritePerm));
- InstanceUtil.waitTillInstanceReachState(clusterOC, recipeMerlin.getName(), 1,
- CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
+ InstanceUtil.waitTillInstanceReachState(recipeExecLocation.getRecipeOC(clusterOC, clusterOC2),
+ recipeMerlin.getName(), 1, CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
HiveAssert.assertTableEqual(cluster, clusterHC.getTable(dbName, tblName),
cluster2, clusterHC2.getTable(dbName, tblName), new NotifyingAssert(true)
@@ -170,6 +175,8 @@ public class HiveDbDRTest extends BaseTestClass {
@Test
public void drDbAddDropTable() throws Exception {
+ final RecipeExecLocation recipeExecLocation = RecipeExecLocation.SourceCluster;
+ setUp(recipeExecLocation);
final String dbName = "drDbAddDropTable";
final String tblToBeDropped = "table_to_be_dropped";
final String tblToBeDroppedAndAdded = "table_to_be_dropped_and_readded";
@@ -195,8 +202,8 @@ public class HiveDbDRTest extends BaseTestClass {
Assert.assertEquals(Bundle.runFalconCLI(command), 0, "Recipe submission failed.");
- InstanceUtil.waitTillInstanceReachState(clusterOC, recipeMerlin.getName(), 1,
- CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
+ InstanceUtil.waitTillInstanceReachState(recipeExecLocation.getRecipeOC(clusterOC, clusterOC2),
+ recipeMerlin.getName(), 1, CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
final NotifyingAssert anAssert = new NotifyingAssert(true);
HiveAssert.assertDbEqual(cluster, clusterHC.getDatabase(dbName),
@@ -205,16 +212,18 @@ public class HiveDbDRTest extends BaseTestClass {
/* For second replication - a dropped tables is added back */
createVanillaTable(connection, tblToBeDroppedAndAdded);
- InstanceUtil.waitTillInstanceReachState(clusterOC, recipeMerlin.getName(), 2,
- CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
+ InstanceUtil.waitTillInstanceReachState(recipeExecLocation.getRecipeOC(clusterOC, clusterOC2),
+ recipeMerlin.getName(), 2, CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
HiveAssert.assertDbEqual(cluster, clusterHC.getDatabase(dbName),
cluster2, clusterHC2.getDatabase(dbName), anAssert);
anAssert.assertAll();
}
- @Test(enabled = false)
+ @Test
public void drDbNonReplicatableTable() throws Exception {
+ final RecipeExecLocation recipeExecLocation = RecipeExecLocation.SourceCluster;
+ setUp(recipeExecLocation);
final String dbName = "drDbNonReplicatableTable";
final String tblName = "vanillaTable";
final String tblView = "vanillaTableView";
@@ -237,8 +246,8 @@ public class HiveDbDRTest extends BaseTestClass {
runSql(connection, "alter table " + tblOffline + " enable offline");
Assert.assertEquals(Bundle.runFalconCLI(command), 0, "Recipe submission failed.");
- InstanceUtil.waitTillInstanceReachState(clusterOC, recipeMerlin.getName(), 1,
- CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
+ InstanceUtil.waitTillInstanceReachState(recipeExecLocation.getRecipeOC(clusterOC, clusterOC2),
+ recipeMerlin.getName(), 1, CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS);
//vanilla table gets replicated, offline table & view are not replicated
HiveAssert.assertTableEqual(cluster, clusterHC.getTable(dbName, tblName),
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/hive/dr/RecipeExecLocation.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/hive/dr/RecipeExecLocation.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/hive/dr/RecipeExecLocation.java
new file mode 100644
index 0000000..a124082
--- /dev/null
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/hive/dr/RecipeExecLocation.java
@@ -0,0 +1,63 @@
+/**
+ * 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.hive.dr;
+
+import org.apache.falcon.regression.Entities.ClusterMerlin;
+import org.apache.falcon.regression.core.bundle.Bundle;
+import org.apache.oozie.client.OozieClient;
+
+/**
+ * Enum to represent location of recipe execution.
+ */
+enum RecipeExecLocation {
+ SourceCluster {
+ protected OozieClient getRecipeOC(OozieClient srcOC, OozieClient tgtOC) {
+ return srcOC;
+ }
+ protected ClusterMerlin getRecipeCluster(ClusterMerlin srcCM, ClusterMerlin tgtCM) {
+ return srcCM;
+ }
+ protected Bundle getRecipeBundle(Bundle srcBundle, Bundle tgtBundle) {
+ return srcBundle;
+ }
+ },
+ TargetCluster {
+ protected OozieClient getRecipeOC(OozieClient srcOC, OozieClient tgtOC) {
+ return tgtOC;
+ }
+ protected ClusterMerlin getRecipeCluster(ClusterMerlin srcCM, ClusterMerlin tgtCM) {
+ return tgtCM;
+ }
+ protected Bundle getRecipeBundle(Bundle srcBundle, Bundle tgtBundle) {
+ return tgtBundle;
+ }
+ };
+
+ /** Get oozie client for the Oozie that is going to run the recipe.
+ * @param srcOC the oozie client for the source cluster
+ * @param tgtOC the oozie client for the target cluster
+ * @return oozie client for the Oozie that is going to run the recipe
+ */
+ abstract OozieClient getRecipeOC(OozieClient srcOC, OozieClient tgtOC);
+
+ abstract ClusterMerlin getRecipeCluster(ClusterMerlin srcCM, ClusterMerlin tgtCM);
+
+ abstract Bundle getRecipeBundle(Bundle srcBundle, Bundle tgtBundle);
+
+}
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/lineage/ListProcessInstancesTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/lineage/ListProcessInstancesTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/lineage/ListProcessInstancesTest.java
index be8a631..43bdd87 100644
--- a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/lineage/ListProcessInstancesTest.java
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/lineage/ListProcessInstancesTest.java
@@ -40,6 +40,7 @@ import org.testng.asserts.SoftAssert;
import java.io.IOException;
import java.util.Date;
+import java.util.UUID;
/**
* Test list instances api for process.
@@ -58,21 +59,23 @@ public class ListProcessInstancesTest extends BaseTestClass {
@BeforeClass(alwaysRun = true)
public void setUp() throws IOException {
- uploadDirToClusters(aggregateWorkflowDir, OSUtil.RESOURCES_OOZIE);
- startTime = TimeUtil.getTimeWrtSystemTime(-55);
- endTime = TimeUtil.getTimeWrtSystemTime(5);
+ startTime = TimeUtil.getTimeWrtSystemTime(-65);
+ //setting end time in past to make "now" be later then actual end time
+ endTime = TimeUtil.getTimeWrtSystemTime(-5);
LOGGER.info("Time range is between : " + startTime + " and " + endTime);
}
@BeforeMethod(alwaysRun = true)
public void prepareData() throws Exception {
+ uploadDirToClusters(aggregateWorkflowDir, OSUtil.RESOURCES_OOZIE);
bundles[0] = BundleUtil.readELBundle();
bundles[0] = new Bundle(bundles[0], servers.get(0));
bundles[0].generateUniqueBundle(this);
//prepare process
bundles[0].setProcessWorkflow(aggregateWorkflowDir);
bundles[0].setInputFeedDataPath(feedDataLocation);
- bundles[0].setOutputFeedLocationData(baseTestHDFSDir + "/output" + MINUTE_DATE_PATTERN);
+ String suffix = UUID.randomUUID().toString();
+ bundles[0].setOutputFeedLocationData(baseTestHDFSDir + "/output/" + suffix + MINUTE_DATE_PATTERN);
bundles[0].setProcessValidity(startTime, endTime);
bundles[0].setProcessConcurrency(3);
bundles[0].submitAndScheduleProcess();
@@ -94,6 +97,9 @@ public class ListProcessInstancesTest extends BaseTestClass {
*/
@Test
public void testProcessOrderBy() throws Exception {
+ //provide data for 4th and 5th instances (fyi: indexing starts from 0th instance)
+ OozieUtil.createMissingDependencies(cluster, EntityType.PROCESS, processName, 0, 3);
+ OozieUtil.createMissingDependencies(cluster, EntityType.PROCESS, processName, 0, 4);
SoftAssert softAssert = new SoftAssert();
//orderBy startTime descending order
InstancesResult r = prism.getProcessHelper().listInstances(processName,
@@ -152,6 +158,7 @@ public class ListProcessInstancesTest extends BaseTestClass {
}
/**
+ * List process instances using orderBy - status, -startTime, -endTime params
* List process instances using -offset and -numResults params expecting list of process
* instances to start at the right offset and give expected number of instances.
*/
@@ -214,6 +221,10 @@ public class ListProcessInstancesTest extends BaseTestClass {
*/
@Test
public void testProcessFilterBy() throws Exception {
+ //provide data for 4th and 5th instances (fyi: indexing starts from 0th instance)
+ OozieUtil.createMissingDependencies(cluster, EntityType.PROCESS, processName, 0, 3);
+ OozieUtil.createMissingDependencies(cluster, EntityType.PROCESS, processName, 0, 4);
+
//test with simple filters
InstancesResult r = prism.getProcessHelper().listInstances(processName,
"filterBy=STATUS:RUNNING", null);
@@ -293,9 +304,13 @@ public class ListProcessInstancesTest extends BaseTestClass {
+ "&end=" + TimeUtil.addMinsToTime(startTime, 16), null);
InstanceUtil.validateResponse(r, 1, 0, 0, 1, 0);
- //only start, actual startTime (end is automatically set to start + frequency * 10)
+ //only start, actual startTime (end is automatically set to now - which is later then validity end time)
r = prism.getProcessHelper().listInstances(processName, "start=" + startTime, null);
- InstanceUtil.validateResponse(r, 10, 3, 0, 7, 0);
+ InstanceUtil.validateResponse(r, 10, 1, 0, 9, 0);
+
+ //the same without start, end should be set to now
+ r = prism.getProcessHelper().listInstances(processName, "", null);
+ InstanceUtil.validateResponse(r, 10, 1, 0, 9, 0);
//only start, greater then actual startTime
r = prism.getProcessHelper().listInstances(processName,
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/ClusterSetupTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/ClusterSetupTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/ClusterSetupTest.java
index b0ddcf3..5efa5b2 100644
--- a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/ClusterSetupTest.java
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/ClusterSetupTest.java
@@ -83,6 +83,7 @@ public class ClusterSetupTest extends BaseUITestClass{
@Test
public void testDefaultScenario()
throws URISyntaxException, AuthenticationException, InterruptedException, IOException {
+ Assert.assertFalse(clusterSetup.isXmlPreviewExpanded(), "Xml preview should be collapsed by default.");
clusterSetup.fillForm(sourceCluster);
clusterSetup.clickNext();
clusterSetup.clickPrevious();
@@ -93,6 +94,9 @@ public class ClusterSetupTest extends BaseUITestClass{
clusterSetup.clickSave();
String alertText = clusterSetup.getActiveAlertText();
Assert.assertEquals(alertText, "falcon/default/Submit successful (cluster) " + sourceCluster.getName());
+ //check the same via notifications bar
+ clusterSetup.getPageHeader().validateNotificationCountAndCheckLast(1,
+ "falcon/default/Submit successful (cluster) " + sourceCluster.getName());
ClusterMerlin definition = new ClusterMerlin(cluster.getClusterHelper()
.getEntityDefinition(bundles[0].getClusterElement().toString()).getMessage());
//definition should be the same that the source
@@ -106,11 +110,11 @@ public class ClusterSetupTest extends BaseUITestClass{
@Test
public void testXmlPreview() {
clusterSetup.fillForm(sourceCluster);
- ClusterMerlin generalStepPreview = clusterSetup.getXmlPreview();
+ ClusterMerlin generalStepPreview = clusterSetup.getEntityFromXMLPreview();
cleanGeneralPreview(generalStepPreview);
sourceCluster.assertEquals(generalStepPreview);
clusterSetup.clickNext();
- ClusterMerlin summaryStepPreview = clusterSetup.getXmlPreview();
+ ClusterMerlin summaryStepPreview = clusterSetup.getEntityFromXMLPreview();
sourceCluster.assertEquals(summaryStepPreview);
generalStepPreview.assertEquals(summaryStepPreview);
}
@@ -145,7 +149,7 @@ public class ClusterSetupTest extends BaseUITestClass{
clusterSetup.fillForm(sourceCluster);
//check without extra location
- ClusterMerlin preview = clusterSetup.getXmlPreview();
+ ClusterMerlin preview = clusterSetup.getEntityFromXMLPreview();
cleanGeneralPreview(preview);
sourceCluster.assertEquals(preview);
@@ -157,7 +161,7 @@ public class ClusterSetupTest extends BaseUITestClass{
clusterSetup.clickAddLocation();
clusterSetup.fillAdditionalLocation(location);
Assert.assertTrue(clusterSetup.checkElementByContent("input", path), "Location should be present.");
- preview = clusterSetup.getXmlPreview();
+ preview = clusterSetup.getEntityFromXMLPreview();
cleanGeneralPreview(preview);
//add location to source to compare equality
sourceCluster.addLocation(ClusterLocationType.WORKING, path);
@@ -166,7 +170,7 @@ public class ClusterSetupTest extends BaseUITestClass{
//delete location and check results
clusterSetup.clickDeleteLocation();
Assert.assertFalse(clusterSetup.checkElementByContent("input", path), "Location should be absent.");
- preview = clusterSetup.getXmlPreview();
+ preview = clusterSetup.getEntityFromXMLPreview();
cleanGeneralPreview(preview);
//remove location from source to check equality
int last = sourceCluster.getLocations().getLocations().size() - 1;
@@ -183,7 +187,7 @@ public class ClusterSetupTest extends BaseUITestClass{
clusterSetup.fillForm(sourceCluster);
//check without extra tag
- ClusterMerlin preview = clusterSetup.getXmlPreview();
+ ClusterMerlin preview = clusterSetup.getEntityFromXMLPreview();
cleanGeneralPreview(preview);
sourceCluster.assertEquals(preview);
@@ -192,7 +196,7 @@ public class ClusterSetupTest extends BaseUITestClass{
clusterSetup.addTag("myTag2", "myValue2");
Assert.assertTrue(clusterSetup.checkElementByContent("input", "myTag2"), "Tag should be present");
Assert.assertTrue(clusterSetup.checkElementByContent("input", "myValue2"), "Tag should be present");
- preview = clusterSetup.getXmlPreview();
+ preview = clusterSetup.getEntityFromXMLPreview();
cleanGeneralPreview(preview);
//add tag to source to compare equality
sourceCluster.setTags("myTag1=myValue1,myTag2=myValue2");
@@ -202,7 +206,7 @@ public class ClusterSetupTest extends BaseUITestClass{
clusterSetup.clickDeleteTag();
Assert.assertFalse(clusterSetup.checkElementByContent("input", "myTag2"), "Tag should be absent.");
Assert.assertFalse(clusterSetup.checkElementByContent("input", "myValue2"), "Tag should be absent.");
- preview = clusterSetup.getXmlPreview();
+ preview = clusterSetup.getEntityFromXMLPreview();
cleanGeneralPreview(preview);
//remove location from source to check equality
sourceCluster.setTags("myTag1=myValue1");
@@ -254,11 +258,27 @@ public class ClusterSetupTest extends BaseUITestClass{
clusterSetup.clickNext();
clusterSetup.clickSave();
String alertMessage = clusterSetup.getActiveAlertText();
- Assert.assertEquals(alertMessage,
+ Assert.assertTrue(alertMessage.contains(String.format("Location %s for cluster %s must exist.",
+ nonExistent, sourceCluster.getName())), "Alert message should match to expected.");
+ //check the same through notification bar
+ clusterSetup.getPageHeader().validateNotificationCountAndCheckLast(1,
String.format("Location %s for cluster %s must exist.", nonExistent, sourceCluster.getName()));
}
/**
+ * Validate alert lifetime.
+ */
+ @Test
+ public void testValidateAlertLifeTime() throws IOException {
+ String nonExistent = "/non-existent-directory";
+ sourceCluster.getLocation(ClusterLocationType.STAGING).setPath(nonExistent);
+ clusterSetup.fillForm(sourceCluster);
+ clusterSetup.clickNext();
+ clusterSetup.clickSave();
+ clusterSetup.validateAlertLifetime();
+ }
+
+ /**
* Populate cluster with properties. Click Edit XML. Change cluster name and
* description, add registry interface. Check that they were enabled and populated
* in wizard.
@@ -283,7 +303,7 @@ public class ClusterSetupTest extends BaseUITestClass{
sourceCluster.getInterfaces().getInterfaces().add(iFace);
//populate it to xmlPreview
- clusterSetup.setClusterXml(sourceCluster.toString());
+ clusterSetup.setXmlPreview(sourceCluster.toString());
//check values on wizard
registryEndpoint = clusterSetup.getInterfaceEndpoint(Interfacetype.REGISTRY);
@@ -304,24 +324,24 @@ public class ClusterSetupTest extends BaseUITestClass{
@Test
public void testEditXmlInvalidValues(){
clusterSetup.fillForm(sourceCluster);
- ClusterMerlin initialPreview = clusterSetup.getXmlPreview();
+ ClusterMerlin initialPreview = clusterSetup.getEntityFromXMLPreview();
//break xml
String brokenXml = new ClusterMerlin(sourceCluster.toString()).toString();
brokenXml = brokenXml.substring(0, brokenXml.length() - 3);
//enter it into xml preview form
- clusterSetup.setClusterXml(brokenXml);
+ clusterSetup.setXmlPreview(brokenXml);
//compare preview before and after changes
- ClusterMerlin finalPreview = clusterSetup.getXmlPreview();
+ ClusterMerlin finalPreview = clusterSetup.getEntityFromXMLPreview();
Assert.assertEquals(initialPreview, finalPreview, "Broken xml shouldn't be accepted.");
//change properties to malformed
sourceCluster.setName("abc123!@#");
//enter it into xml preview form
- clusterSetup.setClusterXml(sourceCluster.toString());
+ clusterSetup.setXmlPreview(sourceCluster.toString());
//check the value on a wizard
Assert.assertEquals(clusterSetup.getName(), sourceCluster.getName(), "Malformed name should be accepted.");
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/FeedSetupTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/FeedSetupTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/FeedSetupTest.java
index 47b1d19..e18fb47 100644
--- a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/FeedSetupTest.java
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/FeedSetupTest.java
@@ -123,6 +123,7 @@ public class FeedSetupTest extends BaseUITestClass{
*/
@Test
public void testWizardDefaultScenario() throws Exception {
+ Assert.assertFalse(feedWizardPage.isXmlPreviewExpanded(), "Xml preview should be collapsed by default.");
feed.setTags(getRandomTags());
feed.setGroups("groups");
feed.setAvailabilityFlag("_SUCCESS");
@@ -201,7 +202,7 @@ public class FeedSetupTest extends BaseUITestClass{
// Set values on the General Info Page
feedWizardPage.setFeedGeneralInfo(feed);
- FeedMerlin feedFromXML = feedWizardPage.getFeedMerlinFromFeedXml();
+ FeedMerlin feedFromXML = feedWizardPage.getEntityFromXMLPreview();
// Assert all the values entered on the General Info Page
feed.assertGeneralProperties(feedFromXML);
@@ -209,7 +210,7 @@ public class FeedSetupTest extends BaseUITestClass{
// Set values on the Properties Info Page
feedWizardPage.clickNext();
feedWizardPage.setFeedPropertiesInfo(feed);
- feedFromXML = feedWizardPage.getFeedMerlinFromFeedXml();
+ feedFromXML = feedWizardPage.getEntityFromXMLPreview();
// Assert all the values entered on the Properties Info Page
feed.assertPropertiesInfo(feedFromXML);
@@ -217,7 +218,7 @@ public class FeedSetupTest extends BaseUITestClass{
// Set values on the Location Info Page
feedWizardPage.clickNext();
feedWizardPage.setFeedLocationInfo(feed);
- feedFromXML = feedWizardPage.getFeedMerlinFromFeedXml();
+ feedFromXML = feedWizardPage.getEntityFromXMLPreview();
// Assert all the values entered on the Location Info Page
feed.assertLocationInfo(feedFromXML);
@@ -226,7 +227,7 @@ public class FeedSetupTest extends BaseUITestClass{
// Set values on the Cluster Info Page
feedWizardPage.clickNext();
feedWizardPage.setFeedClustersInfo(feed);
- feedFromXML = feedWizardPage.getFeedMerlinFromFeedXml();
+ feedFromXML = feedWizardPage.getEntityFromXMLPreview();
// Assert all the values entered on the Cluster Info Page
@@ -253,15 +254,13 @@ public class FeedSetupTest extends BaseUITestClass{
feedWizardPage.setFeedGroups(feed.getGroups());
// Get XML, and set tag and group back to null
- FeedMerlin feedFromXML = feedWizardPage.getFeedMerlinFromFeedXml();
+ FeedMerlin feedFromXML = feedWizardPage.getEntityFromXMLPreview();
feedFromXML.setTags(null);
feedFromXML.setGroups(null);
// Now click EditXML and set the updated XML here
- feedWizardPage.clickEditXml();
String xmlToString = feedFromXML.toString();
- feedWizardPage.setFeedXml(xmlToString);
- feedWizardPage.clickEditXml();
+ feedWizardPage.setXmlPreview(xmlToString);
// Assert that there is only one Tag on the Wizard window
feedWizardPage.isTagsDisplayed(0, true);
@@ -282,10 +281,8 @@ public class FeedSetupTest extends BaseUITestClass{
feedFromXML.setGroups("groups_new");
// Now click EditXML and set the updated XML here
- feedWizardPage.clickEditXml();
xmlToString = feedFromXML.toString();
- feedWizardPage.setFeedXml(xmlToString);
- feedWizardPage.clickEditXml();
+ feedWizardPage.setXmlPreview(xmlToString);
// Assert that there are two Tags on the Wizard window
feedWizardPage.isTagsDisplayed(0, true);
@@ -340,7 +337,7 @@ public class FeedSetupTest extends BaseUITestClass{
// Set values on the General Info Page
feedWizardPage.setFeedGeneralInfo(feed);
- FeedMerlin feedFromXML = feedWizardPage.getFeedMerlinFromFeedXml();
+ FeedMerlin feedFromXML = feedWizardPage.getEntityFromXMLPreview();
// Assert all the values entered on the General Info Page
feed.assertGeneralProperties(feedFromXML);
@@ -367,7 +364,7 @@ public class FeedSetupTest extends BaseUITestClass{
feedWizardPage.isTagsDisplayed(1, true);
// Get feed from XML Preview
- FeedMerlin feedFromXML = feedWizardPage.getFeedMerlinFromFeedXml();
+ FeedMerlin feedFromXML = feedWizardPage.getEntityFromXMLPreview();
// Assert Tag values in the XML Preview
Assert.assertEquals(feedFromXML.getTags(), feed.getTags());
@@ -380,7 +377,7 @@ public class FeedSetupTest extends BaseUITestClass{
feedWizardPage.isTagsDisplayed(1, false);
// Get feed from XML Preview
- feedFromXML = feedWizardPage.getFeedMerlinFromFeedXml();
+ feedFromXML = feedWizardPage.getEntityFromXMLPreview();
// Assert that there are is only one Tag in the XML Preview
Assert.assertEquals(feedFromXML.getTags(), "first=yes",
"Unexpected Tags on the XML preview");
@@ -470,7 +467,7 @@ public class FeedSetupTest extends BaseUITestClass{
// Set values on the Properties Info Page
feedWizardPage.clickNext();
feedWizardPage.setFeedPropertiesInfo(feed);
- FeedMerlin feedFromXML = feedWizardPage.getFeedMerlinFromFeedXml();
+ FeedMerlin feedFromXML = feedWizardPage.getEntityFromXMLPreview();
// Assert all the values entered on the Properties Info Page
feed.assertPropertiesInfo(feedFromXML);
@@ -499,15 +496,13 @@ public class FeedSetupTest extends BaseUITestClass{
feedWizardPage.setFeedLateArrivalCutOffUnit(feed.getLateArrival().getCutOff().getTimeUnit().toString());
// Get XML, and set Frequency and Late Arrival back to null
- FeedMerlin feedFromXML = feedWizardPage.getFeedMerlinFromFeedXml();
+ FeedMerlin feedFromXML = feedWizardPage.getEntityFromXMLPreview();
feedFromXML.setFrequency(null);
feedFromXML.setLateArrival(null);
// Now click EditXML and set the updated XML here
- feedWizardPage.clickEditXml();
String xmlToString = feedFromXML.toString();
- feedWizardPage.setFeedXml(xmlToString);
- feedWizardPage.clickEditXml();
+ feedWizardPage.setXmlPreview(xmlToString);
// Assert that the Frequency value is empty on the Wizard window
Assert.assertEquals(feedWizardPage.getFeedFrequencyQuantityText(), "",
@@ -523,10 +518,8 @@ public class FeedSetupTest extends BaseUITestClass{
feedFromXML.getLateArrival().setCutOff(new Frequency("1", Frequency.TimeUnit.days));
// Now click EditXML and set the updated XML here
- feedWizardPage.clickEditXml();
xmlToString = feedFromXML.toString();
- feedWizardPage.setFeedXml(xmlToString);
- feedWizardPage.clickEditXml();
+ feedWizardPage.setXmlPreview(xmlToString);
// Assert that the Frequency values are correct on the Wizard window
Assert.assertEquals(feedWizardPage.getFeedFrequencyQuantityText(), "5",
@@ -595,7 +588,7 @@ public class FeedSetupTest extends BaseUITestClass{
feedWizardPage.isPropertyDisplayed(1, true);
// Get feed from XML Preview
- FeedMerlin feedFromXML = feedWizardPage.getFeedMerlinFromFeedXml();
+ FeedMerlin feedFromXML = feedWizardPage.getEntityFromXMLPreview();
// Assert Property values in the XML Preview
Assert.assertEquals(feedFromXML.getProperties().getProperties().get(0).getName(),
@@ -621,7 +614,7 @@ public class FeedSetupTest extends BaseUITestClass{
// Get feed from XML Preview
- feedFromXML = feedWizardPage.getFeedMerlinFromFeedXml();
+ feedFromXML = feedWizardPage.getEntityFromXMLPreview();
// Assert Property value in the XML Preview
Assert.assertEquals(feedFromXML.getProperties().getProperties().get(0).getName(),
@@ -741,7 +734,7 @@ public class FeedSetupTest extends BaseUITestClass{
feedWizardPage.setFeedLocationInfo(feed);
// Get feed from XML Preview
- FeedMerlin feedFromXML = feedWizardPage.getFeedMerlinFromFeedXml();
+ FeedMerlin feedFromXML = feedWizardPage.getEntityFromXMLPreview();
// Assert all the values entered on the Location Info Page
feed.assertLocationInfo(feedFromXML);
@@ -752,13 +745,11 @@ public class FeedSetupTest extends BaseUITestClass{
feedFromXML.getLocations().getLocations().get(2).setPath(baseTestHDFSDir + "/newFalcon/clicksMetaData");
// Now click EditXML and set the updated XML here
- feedWizardPage.clickEditXml();
String xmlToString = feedFromXML.toString();
- feedWizardPage.setFeedXml(xmlToString);
- feedWizardPage.clickEditXml();
+ feedWizardPage.setXmlPreview(xmlToString);
// Get feed from XML Preview
- feedFromXML = feedWizardPage.getFeedMerlinFromFeedXml();
+ feedFromXML = feedWizardPage.getEntityFromXMLPreview();
// Assert all the values on the Location Info Page
Assert.assertEquals(feedFromXML.getLocations().getLocations().get(0).getPath(),
baseTestHDFSDir + "/newInput/${YEAR}/${MONTH}/${DAY}/${HOUR}/${MINUTE}");
@@ -877,7 +868,7 @@ public class FeedSetupTest extends BaseUITestClass{
feedWizardPage.clickNext();
// Get feed from XML Preview
- FeedMerlin feedFromXML = feedWizardPage.getFeedMerlinFromFeedXml();
+ FeedMerlin feedFromXML = feedWizardPage.getEntityFromXMLPreview();
// Assert all the values entered on the Location Info Page
feed.assertLocationInfo(feedFromXML);
@@ -895,7 +886,7 @@ public class FeedSetupTest extends BaseUITestClass{
feedWizardPage.clickNext();
// Get feed from XML Preview
- feedFromXML = feedWizardPage.getFeedMerlinFromFeedXml();
+ feedFromXML = feedWizardPage.getEntityFromXMLPreview();
// Assert the Table Uri value entered on the Location Info Page
Assert.assertEquals(feedFromXML.getTable().getUri(), catalogUri,
@@ -928,7 +919,7 @@ public class FeedSetupTest extends BaseUITestClass{
feedWizardPage.setFeedClustersInfo(feed);
// Get feed from XML Preview
- FeedMerlin feedFromXML = feedWizardPage.getFeedMerlinFromFeedXml();
+ FeedMerlin feedFromXML = feedWizardPage.getEntityFromXMLPreview();
// Assert all the values on the Cluster Info Page
feed.assertClusterInfo(feedFromXML);
@@ -946,13 +937,11 @@ public class FeedSetupTest extends BaseUITestClass{
// Now click EditXML and set the updated XML here
- feedWizardPage.clickEditXml();
String xmlToString = feedFromXML.toString();
- feedWizardPage.setFeedXml(xmlToString);
- feedWizardPage.clickEditXml();
+ feedWizardPage.setXmlPreview(xmlToString);
// Get feed from XML Preview
- feedFromXML = feedWizardPage.getFeedMerlinFromFeedXml();
+ feedFromXML = feedWizardPage.getEntityFromXMLPreview();
// Assert all the values on the Location Info Page
Assert.assertEquals(feedFromXML.getClusters().getClusters().get(0)
.getLocations().getLocations().get(0).getPath(),
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/HomePageTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/HomePageTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/HomePageTest.java
index 20864f6..46ace0f 100644
--- a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/HomePageTest.java
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/HomePageTest.java
@@ -172,8 +172,8 @@ public class HomePageTest extends BaseUITestClass {
alertText = homePage.getActiveAlertText();
Assert.assertEquals(alertText, "Invalid xml. File not uploaded",
"XML file with invalid text was allowed to be uploaded");
-
-
+ //check the same with notification bar
+ homePage.getPageHeader().validateNotificationCountAndCheckLast(2, "Invalid xml. File not uploaded");
}
/**
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/MirrorSourceTargetOptionsTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/MirrorSourceTargetOptionsTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/MirrorSourceTargetOptionsTest.java
index 552c15e..8bec758 100644
--- a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/MirrorSourceTargetOptionsTest.java
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/MirrorSourceTargetOptionsTest.java
@@ -193,6 +193,8 @@ public class MirrorSourceTargetOptionsTest extends BaseUITestClass{
mirrorPage.save();
Assert.assertTrue(mirrorPage.getActiveAlertText().contains("should be before process end"),
"Warning about wrong Validity should be present");
+ //check the same through notification bar
+ mirrorPage.getPageHeader().validateNotificationCountAndCheckLast(1, "should be before process end");
}
@AfterClass(alwaysRun = true)
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/MirrorTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/MirrorTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/MirrorTest.java
index c54789b..e99202b 100644
--- a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/MirrorTest.java
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/MirrorTest.java
@@ -21,6 +21,7 @@ package org.apache.falcon.regression.searchUI;
import org.apache.falcon.cli.FalconCLI;
import org.apache.falcon.entity.v0.Frequency;
import org.apache.falcon.entity.v0.cluster.ClusterLocationType;
+import org.apache.falcon.entity.v0.cluster.Interfacetype;
import org.apache.falcon.regression.Entities.ClusterMerlin;
import org.apache.falcon.regression.Entities.ProcessMerlin;
import org.apache.falcon.regression.Entities.RecipeMerlin;
@@ -39,15 +40,18 @@ import org.apache.falcon.regression.ui.search.SearchPage;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.FsPermission;
+import org.apache.hadoop.security.authentication.client.AuthenticationException;
import org.apache.hive.hcatalog.api.HCatClient;
import org.apache.log4j.Logger;
import org.apache.oozie.client.OozieClient;
+import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.io.IOException;
+import java.net.URISyntaxException;
import java.sql.Connection;
import java.util.Arrays;
@@ -75,6 +79,7 @@ public class MirrorTest extends BaseUITestClass {
private Connection connection;
private Connection connection2;
private MirrorWizardPage mirrorPage;
+
/**
* Submit one cluster, 2 feeds and 10 processes with 1 to 10 tags (1st process has 1 tag,
* 2nd - two tags.. 10th has 10 tags).
@@ -82,7 +87,6 @@ public class MirrorTest extends BaseUITestClass {
* @throws IOException
* @throws AuthenticationException
* @throws InterruptedException
- * @throws JAXBException
*/
@BeforeMethod(alwaysRun = true)
public void setup() throws Exception {
@@ -148,7 +152,7 @@ public class MirrorTest extends BaseUITestClass {
hdfsRecipe.withSourceDir(hdfsSrcDir).withTargetDir(hdfsTgtDir);
hdfsRecipe.setTags(Arrays.asList("key1=val1", "key2=val2", "key3=val3"));
- mirrorPage.applyRecipe(hdfsRecipe);
+ mirrorPage.applyRecipe(hdfsRecipe, true);
mirrorPage.next();
mirrorPage.save();
@@ -169,7 +173,7 @@ public class MirrorTest extends BaseUITestClass {
recipeMerlin.withSourceDb(dbName);
recipeMerlin.withSourceTable(tblName);
recipeMerlin.setTags(Arrays.asList("key1=val1", "key2=val2", "key3=val3"));
- mirrorPage.applyRecipe(recipeMerlin);
+ mirrorPage.applyRecipe(recipeMerlin, true);
mirrorPage.next();
mirrorPage.save();
AssertUtil.assertSucceeded(prism.getProcessHelper().getStatus(
@@ -186,6 +190,66 @@ public class MirrorTest extends BaseUITestClass {
}
/**
+ * If "send alerts to" is empty on HiveDR UI, default value for drNotificationReceivers property must be "NA".
+ */
+ @Test
+ public void testSendAlertsDefaultValue()
+ throws InterruptedException, IOException, URISyntaxException, AuthenticationException {
+ recipeMerlin.withSourceDb(DB_NAME);
+ recipeMerlin.withSourceTable(TBL1_NAME);
+ mirrorPage.applyRecipe(recipeMerlin, false);
+ mirrorPage.next();
+ mirrorPage.save();
+ ProcessMerlin process = bundles[0].getProcessObject();
+ process.setName(recipeMerlin.getName());
+ process = new ProcessMerlin(cluster.getProcessHelper().getEntityDefinition(process.toString()).getMessage());
+ String drNotificationReceivers = process.getProperty("drNotificationReceivers");
+ Assert.assertTrue(drNotificationReceivers != null && drNotificationReceivers.equals("NA"),
+ "Default value for drNotificationReceivers should be NA.");
+
+ /* particular check that on table replication scenario UI doesn't pick up thrift server
+ end point in place of Hive server2 end point*/
+ String expectedUri = recipeMerlin.getTgtCluster().getInterfaceEndpoint(Interfacetype.REGISTRY)
+ .replace("thrift", "hive2").replace("9083", "10000");
+ Assert.assertEquals(process.getProperty("targetHiveServer2Uri"), expectedUri,
+ "Hive server2 end point should be picked by UI.");
+ expectedUri = recipeMerlin.getSrcCluster().getInterfaceEndpoint(Interfacetype.REGISTRY)
+ .replace("thrift", "hive2").replace("9083", "10000");
+ Assert.assertEquals(process.getProperty("sourceHiveServer2Uri"), expectedUri,
+ "Hive server2 end point should be picked by UI.");
+ }
+
+ /**
+ * Test that Hive DR UI doesn't picks thrift server end point in place of Hive server2 end point.
+ * Test that specified HDFS target staging path on Hive DR UI, isn't getting assigned to "*".
+ */
+ @Test
+ public void testHDFSTargetStagingPath()
+ throws URISyntaxException, AuthenticationException, InterruptedException, IOException {
+ recipeMerlin.withSourceDb(DB_NAME);
+ mirrorPage.applyRecipe(recipeMerlin, false);
+ mirrorPage.next();
+ mirrorPage.save();
+ ProcessMerlin process = bundles[0].getProcessObject();
+ process.setName(recipeMerlin.getName());
+ process = new ProcessMerlin(cluster.getProcessHelper().getEntityDefinition(process.toString()).getMessage());
+
+ // check that that Hive DR UI doesn't picks thrift server end point in place of Hive server2 end point
+ String expectedUri = recipeMerlin.getTgtCluster().getInterfaceEndpoint(Interfacetype.REGISTRY)
+ .replace("thrift", "hive2").replace("9083", "10000");
+ Assert.assertEquals(process.getProperty("targetHiveServer2Uri"), expectedUri,
+ "Hive server2 end point should be picked by UI.");
+ expectedUri = recipeMerlin.getSrcCluster().getInterfaceEndpoint(Interfacetype.REGISTRY)
+ .replace("thrift", "hive2").replace("9083", "10000");
+ Assert.assertEquals(process.getProperty("sourceHiveServer2Uri"), expectedUri,
+ "Hive server2 end point should be picked by UI.");
+
+ //check that that specified HDFS target staging path on Hive DR UI, isn't getting assigned to "*"
+ Assert.assertFalse(process.getProperty("targetStagingPath").equals("*"),
+ "HDFS target staging path shouldn't be assigned to '*'.");
+ }
+
+ /**
* Test recipe with bad acls.
* Set owner/group as invalid string (utf-8, special chars, number).
* Check that user is not allowed to go to the next step and has been notified with an alert.
@@ -197,7 +261,7 @@ public class MirrorTest extends BaseUITestClass {
final String goodAclOwner = MerlinConstants.CURRENT_USER_NAME;
final String goodAclGroup = MerlinConstants.CURRENT_USER_GROUP;
final String goodAclPerms = "777";
- mirrorPage.applyRecipe(recipeMerlin);
+ mirrorPage.applyRecipe(recipeMerlin, true);
NotifyingAssert notifyingAssert = new NotifyingAssert(true);
for(String badAclOwner: new String[] {"utf8\u20ACchar", "speci@l", "123"}) {
mirrorPage.setAclOwner(badAclOwner);
@@ -253,7 +317,7 @@ public class MirrorTest extends BaseUITestClass {
public void testHiveAdvancedInvalidStaging() {
recipeMerlin.withSourceDb(DB_NAME);
recipeMerlin.setTags(Arrays.asList("key1=val1", "key2=val2", "key3=val3"));
- mirrorPage.applyRecipe(recipeMerlin);
+ mirrorPage.applyRecipe(recipeMerlin, true);
NotifyingAssert notifyingAssert = new NotifyingAssert(true);
final String goodSrcStaging = recipeMerlin.getSrcCluster().getLocation(ClusterLocationType.STAGING).getPath();
final String goodTgtStaging = recipeMerlin.getTgtCluster().getLocation(ClusterLocationType.STAGING).getPath();
@@ -297,7 +361,7 @@ public class MirrorTest extends BaseUITestClass {
public void testHiveAdvancedStagingAcl() throws Exception {
recipeMerlin.withSourceDb(DB_NAME);
recipeMerlin.setTags(Arrays.asList("key1=val1", "key2=val2", "key3=val3"));
- mirrorPage.applyRecipe(recipeMerlin);
+ mirrorPage.applyRecipe(recipeMerlin, true);
NotifyingAssert notifyingAssert = new NotifyingAssert(true);
final String goodSrcStaging = recipeMerlin.getSrcCluster().getLocation(ClusterLocationType.STAGING).getPath();
final String goodTgtStaging = recipeMerlin.getTgtCluster().getLocation(ClusterLocationType.STAGING).getPath();
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/ProcessSetupTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/ProcessSetupTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/ProcessSetupTest.java
index 728646f..eae5137 100644
--- a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/ProcessSetupTest.java
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/ProcessSetupTest.java
@@ -153,6 +153,7 @@ public class ProcessSetupTest extends BaseUITestClass {
*/
@Test
public void testGeneralStepDefaultScenario() throws Exception {
+ Assert.assertFalse(processWizardPage.isXmlPreviewExpanded(), "Xml preview should be collapsed by default.");
processWizardPage.setProcessGeneralInfo(process);
processWizardPage.clickNext();
@@ -172,7 +173,7 @@ public class ProcessSetupTest extends BaseUITestClass {
processWizardPage.setProcessGeneralInfo(process);
// Get process from XML Preview
- ProcessMerlin processFromXML = processWizardPage.getProcessMerlinFromProcessXml();
+ ProcessMerlin processFromXML = processWizardPage.getEntityFromXMLPreview();
// Assert all the values entered on the General Info Page
LOGGER.info(String.format("Comparing source process: %n%s%n and preview: %n%s%n.", process, processFromXML));
@@ -196,14 +197,12 @@ public class ProcessSetupTest extends BaseUITestClass {
processWizardPage.setTags(process.getTags());
// Get XML, and set tag and group back to null
- ProcessMerlin processFromXML = processWizardPage.getProcessMerlinFromProcessXml();
+ ProcessMerlin processFromXML = processWizardPage.getEntityFromXMLPreview();
processFromXML.setTags(null);
// Now click EditXML and set the updated XML here
- processWizardPage.clickEditXml();
String xmlToString = processFromXML.toString();
- processWizardPage.setProcessXml(xmlToString);
- processWizardPage.clickEditXml();
+ processWizardPage.setXmlPreview(xmlToString);
Thread.sleep(1000);
// Assert that there is only one Tag on the Wizard window
@@ -222,10 +221,8 @@ public class ProcessSetupTest extends BaseUITestClass {
processFromXML.getWorkflow().setVersion("pig-0.13.0");
// Now click EditXML and set the updated XML here
- processWizardPage.clickEditXml();
xmlToString = processFromXML.toString();
- processWizardPage.setProcessXml(xmlToString);
- processWizardPage.clickEditXml();
+ processWizardPage.setXmlPreview(xmlToString);
// Assert that there are two Tags on the Wizard window
processWizardPage.isTagsDisplayed(0, true);
@@ -316,7 +313,7 @@ public class ProcessSetupTest extends BaseUITestClass {
processWizardPage.setProcessPropertiesInfo(process);
// Get process from XML Preview
- ProcessMerlin processFromXML = processWizardPage.getProcessMerlinFromProcessXml();
+ ProcessMerlin processFromXML = processWizardPage.getEntityFromXMLPreview();
// Assert all the values entered on the Properties Page
LOGGER.info(String.format("Comparing source process: %n%s%n and preview: %n%s%n.", process, processFromXML));
@@ -343,15 +340,13 @@ public class ProcessSetupTest extends BaseUITestClass {
processWizardPage.setMaxParallelInstances(5);
// Get process from XML Preview
- ProcessMerlin processFromXML = processWizardPage.getProcessMerlinFromProcessXml();
+ ProcessMerlin processFromXML = processWizardPage.getEntityFromXMLPreview();
processFromXML.setFrequency(null);
processFromXML.setParallel(1);
// Now click EditXML and set the updated XML here
- processWizardPage.clickEditXml();
String xmlToString = processFromXML.toString();
- processWizardPage.setProcessXml(xmlToString);
- processWizardPage.clickEditXml();
+ processWizardPage.setXmlPreview(xmlToString);
// Assert Frequency and Parallel values
Assert.assertEquals(processWizardPage.getFrequencyQuantityText(), "",
@@ -360,17 +355,15 @@ public class ProcessSetupTest extends BaseUITestClass {
"Unexpected Parallel on the Wizard window");
// Get process from XML Preview
- processFromXML = processWizardPage.getProcessMerlinFromProcessXml();
+ processFromXML = processWizardPage.getEntityFromXMLPreview();
// Set TimeZone and Order
TimeZone tz = TimeZone.getTimeZone("GMT-08:00");
processFromXML.setTimezone(tz);
processFromXML.setOrder(ExecutionType.LIFO);
// Now click EditXML and set the updated XML here
- processWizardPage.clickEditXml();
xmlToString = processFromXML.toString();
- processWizardPage.setProcessXml(xmlToString);
- processWizardPage.clickEditXml();
+ processWizardPage.setXmlPreview(xmlToString);
// Assert TimeZone and Order
Assert.assertEquals(processWizardPage.getOrderText(), "LIFO",
@@ -511,7 +504,7 @@ public class ProcessSetupTest extends BaseUITestClass {
// Add clusters
processWizardPage.setClusters(process.getClusters());
- ProcessMerlin xmlPreview = processWizardPage.getProcessMerlinFromProcessXml();
+ ProcessMerlin xmlPreview = processWizardPage.getEntityFromXMLPreview();
//compare clusters
LOGGER.info(String.format("Comparing clusters of process: %n%s%n and preview: %n%s%n.", process, xmlPreview));
@@ -519,7 +512,7 @@ public class ProcessSetupTest extends BaseUITestClass {
//delete one cluster and repeat the check
processWizardPage.deleteLastCluster();
- xmlPreview = processWizardPage.getProcessMerlinFromProcessXml();
+ xmlPreview = processWizardPage.getEntityFromXMLPreview();
process.getClusters().getClusters().remove(1);
//compare clusters
@@ -553,7 +546,7 @@ public class ProcessSetupTest extends BaseUITestClass {
processWizardPage.setClusters(process.getClusters());
//compare preview and source data
- ProcessMerlin xmlPreview = processWizardPage.getProcessMerlinFromProcessXml();
+ ProcessMerlin xmlPreview = processWizardPage.getEntityFromXMLPreview();
LOGGER.info(String.format("Comparing clusters of process: %n%s%n and preview: %n%s%n.", process, xmlPreview));
ProcessMerlin.assertClustersEqual(process.getClusters().getClusters(), xmlPreview.getClusters().getClusters());
@@ -561,9 +554,7 @@ public class ProcessSetupTest extends BaseUITestClass {
Date date = new Date();
xmlPreview.getClusters().getClusters().get(0).getValidity().setEnd(date);
xmlPreview.getClusters().getClusters().get(0).setName(clusterMerlin.getName());
- processWizardPage.clickEditXml();
- processWizardPage.setProcessXml(xmlPreview.toString());
- processWizardPage.clickEditXml();
+ processWizardPage.setXmlPreview(xmlPreview.toString());
//check that validity end is changed on wizard
String endUI = processWizardPage.getValidityEnd();
@@ -581,9 +572,7 @@ public class ProcessSetupTest extends BaseUITestClass {
processCluster.setName(firstClusterName);
processCluster.setValidity(xmlPreview.getClusters().getClusters().get(0).getValidity());
process.addProcessCluster(processCluster);
- processWizardPage.clickEditXml();
- processWizardPage.setProcessXml(xmlPreview.toString());
- processWizardPage.clickEditXml();
+ processWizardPage.setXmlPreview(xmlPreview.toString());
//check that changes are reflected on wizard
int finalCount = processWizardPage.getWizardClusterCount();
@@ -797,7 +786,7 @@ public class ProcessSetupTest extends BaseUITestClass {
"Unexpected Input End on the Wizard window");
// Get process from XML Preview
- ProcessMerlin processFromXML = processWizardPage.getProcessMerlinFromProcessXml();
+ ProcessMerlin processFromXML = processWizardPage.getEntityFromXMLPreview();
// Assert Input values on the XML Preview
LOGGER.info(String.format("Comparing source process: %n%s%n and preview: %n%s%n.", process, processFromXML));
@@ -808,10 +797,8 @@ public class ProcessSetupTest extends BaseUITestClass {
processFromXML.setOutputs(process.getOutputs());
// Now click EditXML and set the updated XML here
- processWizardPage.clickEditXml();
String xmlToString = processFromXML.toString();
- processWizardPage.setProcessXml(xmlToString);
- processWizardPage.clickEditXml();
+ processWizardPage.setXmlPreview(xmlToString);
// Assert Input Name and Output values on Wizard
Assert.assertEquals(processWizardPage.getInputNameText(0), "newInputData",
@@ -867,7 +854,7 @@ public class ProcessSetupTest extends BaseUITestClass {
"Unexpected Input End on the Wizard window");
// Get process from XML Preview
- ProcessMerlin processFromXML = processWizardPage.getProcessMerlinFromProcessXml();
+ ProcessMerlin processFromXML = processWizardPage.getEntityFromXMLPreview();
// Assert Input values on the XML Preview
LOGGER.info(String.format("Comparing source process: %n%s%n and preview: %n%s%n.", process, processFromXML));
@@ -894,7 +881,7 @@ public class ProcessSetupTest extends BaseUITestClass {
"Unexpected Output Instance on the Wizard window");
// Get process from XML Preview
- processFromXML = processWizardPage.getProcessMerlinFromProcessXml();
+ processFromXML = processWizardPage.getEntityFromXMLPreview();
// Assert Output values on the XML Preview
LOGGER.info(String.format("Comparing source process : %n%s%n and preview: %n%s%n.", process, processFromXML));
@@ -1009,7 +996,7 @@ public class ProcessSetupTest extends BaseUITestClass {
//get process from summary and from xml and compare them
ProcessMerlin summaryProcess = ProcessMerlin.getEmptyProcess(process);
summaryProcess = processWizardPage.getProcessFromSummaryBox(summaryProcess);
- ProcessMerlin previewProcess = processWizardPage.getProcessMerlinFromProcessXml();
+ ProcessMerlin previewProcess = processWizardPage.getEntityFromXMLPreview();
summaryProcess.assertEquals(previewProcess);
//add input to preview cluster
@@ -1022,9 +1009,7 @@ public class ProcessSetupTest extends BaseUITestClass {
previewProcess.getInputs().getInputs().add(newInput);
//push new process to xml preview
- processWizardPage.clickEditXml();
- processWizardPage.setProcessXml(previewProcess.toString());
- processWizardPage.clickEditXml();
+ processWizardPage.setXmlPreview(previewProcess.toString());
//get process from summary and check that new input is available
summaryProcess = processWizardPage.getProcessFromSummaryBox(ProcessMerlin.getEmptyProcess(summaryProcess));
@@ -1062,17 +1047,15 @@ public class ProcessSetupTest extends BaseUITestClass {
processWizardPage.clickNext();
//get process from xml preview
- ProcessMerlin previewProcess1 = processWizardPage.getProcessMerlinFromProcessXml();
+ ProcessMerlin previewProcess1 = processWizardPage.getEntityFromXMLPreview();
String processString = previewProcess1.toString();
//damage the xml and populate it back to preview
processString = processString.substring(0, processString.length() - 3);
- processWizardPage.clickEditXml();
- processWizardPage.setProcessXml(processString);
- processWizardPage.clickEditXml();
+ processWizardPage.setXmlPreview(processString);
//get xml preview and compare with initial state
- ProcessMerlin previewProcess2 = processWizardPage.getProcessMerlinFromProcessXml();
+ ProcessMerlin previewProcess2 = processWizardPage.getEntityFromXMLPreview();
previewProcess2.assertEquals(previewProcess1);
}
}
http://git-wip-us.apache.org/repos/asf/falcon/blob/9e6d5a6c/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/security/FalconClientTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/security/FalconClientTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/security/FalconClientTest.java
index d11411b..73273f9 100644
--- a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/security/FalconClientTest.java
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/security/FalconClientTest.java
@@ -25,6 +25,7 @@ import org.apache.falcon.regression.core.supportClasses.ExecResult;
import org.apache.falcon.regression.core.util.AssertUtil;
import org.apache.falcon.regression.core.util.BundleUtil;
import org.apache.falcon.regression.core.util.HadoopUtil;
+import org.apache.falcon.regression.core.util.KerberosHelper;
import org.apache.falcon.regression.core.util.OSUtil;
import org.apache.falcon.regression.testHelper.BaseTestClass;
import org.apache.hadoop.fs.FileSystem;
@@ -80,9 +81,13 @@ public class FalconClientTest extends BaseTestClass {
* able to delete
* @throws Exception
*/
- @Test(enabled = false)
+ @Test(enabled = true)
public void badClusterDelete() throws Exception {
bundles[0].submitClusters(prism);
+ //switch user
+ if (MerlinConstants.IS_SECURE) {
+ KerberosHelper.initUserWithKeytab(MerlinConstants.DIFFERENT_USER_NAME);
+ }
final String clusterXml = bundles[0].getClusters().get(0);
final ExecResult execResult =
prism.getClusterHelper().clientDelete(clusterXml, MerlinConstants.DIFFERENT_USER_NAME);