You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@falcon.apache.org by ro...@apache.org on 2015/05/22 12:32:50 UTC
falcon git commit: FALCON-1229 Tests for instance page on SearchUI.
Contributed by Ruslan Ostafiychuk
Repository: falcon
Updated Branches:
refs/heads/master 637900145 -> 1afb51079
FALCON-1229 Tests for instance page on SearchUI. Contributed by Ruslan Ostafiychuk
Project: http://git-wip-us.apache.org/repos/asf/falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/falcon/commit/1afb5107
Tree: http://git-wip-us.apache.org/repos/asf/falcon/tree/1afb5107
Diff: http://git-wip-us.apache.org/repos/asf/falcon/diff/1afb5107
Branch: refs/heads/master
Commit: 1afb51079a7ebfdaca1cddb39c0c555ea58fdbcd
Parents: 6379001
Author: Ruslan Ostafiychuk <ro...@apache.org>
Authored: Thu May 21 17:31:19 2015 +0300
Committer: Ruslan Ostafiychuk <ro...@apache.org>
Committed: Fri May 22 13:32:09 2015 +0300
----------------------------------------------------------------------
falcon-regression/CHANGES.txt | 2 +
.../falcon/regression/ui/search/EntityPage.java | 7 +
.../regression/ui/search/InstancePage.java | 114 +++++++++++
.../regression/searchUI/InstancePageTest.java | 193 +++++++++++++++++++
4 files changed, 316 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/falcon/blob/1afb5107/falcon-regression/CHANGES.txt
----------------------------------------------------------------------
diff --git a/falcon-regression/CHANGES.txt b/falcon-regression/CHANGES.txt
index c6da36d..b64f11e 100644
--- a/falcon-regression/CHANGES.txt
+++ b/falcon-regression/CHANGES.txt
@@ -5,6 +5,8 @@ Trunk (Unreleased)
INCOMPATIBLE CHANGES
NEW FEATURES
+ FALCON-1229 Tests for instance page on SearchUI (Ruslan Ostafiychuk)
+
FALCON-1216 Cluster setup wizard multiple tests (Paul Isaychuk via Ruslan Ostafiychuk)
FALCON-1202 Add tests for EntityPage (Raghav Kumar Gautam)
http://git-wip-us.apache.org/repos/asf/falcon/blob/1afb5107/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/EntityPage.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/EntityPage.java b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/EntityPage.java
index 0b7057e..5dabc7c 100644
--- a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/EntityPage.java
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/EntityPage.java
@@ -38,6 +38,7 @@ import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
+import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.Select;
import org.testng.asserts.SoftAssert;
@@ -589,6 +590,12 @@ public class EntityPage extends AbstractSearchPage {
}
}
+
+ public InstancePage openInstance(String nominalTime) {
+ instanceListBox.findElement(By.xpath("//button[contains(.,'" + nominalTime + "')]")).click();
+ return PageFactory.initElements(driver, InstancePage.class);
+ }
+
/**
* Class representing summary of one instance.
*/
http://git-wip-us.apache.org/repos/asf/falcon/blob/1afb5107/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/InstancePage.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/InstancePage.java b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/InstancePage.java
new file mode 100644
index 0000000..1fce0a2
--- /dev/null
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/InstancePage.java
@@ -0,0 +1,114 @@
+/**
+ * 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.regression.core.util.UIAssert;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.FindBys;
+import org.openqa.selenium.support.PageFactory;
+
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+
+
+/**
+ * Class representation of Search UI entity page.
+ */
+public class InstancePage extends AbstractSearchPage {
+ private final String nominalTime;
+
+ /**
+ * Possible instance actions available on instance page.
+ */
+ public enum Button {
+ Resume,
+ Suspend,
+ Stop
+ }
+
+ public InstancePage(WebDriver driver) {
+ super(driver);
+ nominalTime = driver.findElement(By.xpath("//h3")).getText().split("\\|")[1].trim();
+ }
+
+
+ @FindBys({
+ @FindBy(className = "detailsBox"),
+ @FindBy(className = "row")
+ })
+ private WebElement detailsBox;
+
+ @FindBys({
+ @FindBy(xpath = "//h3/a")
+ })
+ private WebElement entityLink;
+
+
+
+ @Override
+ public void checkPage() {
+ UIAssert.assertDisplayed(detailsBox, "Dependency box");
+ UIAssert.assertDisplayed(entityLink, "Link to parrent entity");
+ }
+
+ public InstancePage refreshPage() {
+ return backToEntityPage().openInstance(nominalTime);
+ }
+
+ public String getStatus() {
+ return driver.findElement(By.xpath("//h4[@class='instance-title']/span")).getText();
+ }
+
+ public String getEntityName() {
+ return entityLink.getText();
+ }
+
+ public boolean isLineagePresent() {
+ List<WebElement> lineage = driver.findElements(By.className("lineage-graph"));
+ return !lineage.isEmpty() && lineage.get(0).isDisplayed();
+ }
+
+
+ public Set<Button> getButtons(boolean active) {
+ List<WebElement> buttons = detailsBox.findElement(By.className("buttonCell"))
+ .findElements(By.className("btn"));
+ Set<Button> result = EnumSet.noneOf(Button.class);
+ for (WebElement button : buttons) {
+ if ((button.getAttribute("disabled") == null) == active) {
+ result.add(Button.valueOf(button.getText()));
+ }
+ }
+ return result;
+ }
+
+ public void clickButton(Button button) {
+ detailsBox.findElement(By.className("buttonCell"))
+ .findElements(By.className("btn")).get(button.ordinal()).click();
+ waitForAngularToFinish();
+ }
+
+ public EntityPage backToEntityPage() {
+ entityLink.click();
+ return PageFactory.initElements(driver, EntityPage.class);
+ }
+}
http://git-wip-us.apache.org/repos/asf/falcon/blob/1afb5107/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/InstancePageTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/InstancePageTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/InstancePageTest.java
new file mode 100644
index 0000000..0152b42
--- /dev/null
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/InstancePageTest.java
@@ -0,0 +1,193 @@
+/**
+ * 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.searchUI;
+
+import org.apache.falcon.entity.v0.EntityType;
+import org.apache.falcon.entity.v0.Frequency;
+import org.apache.falcon.regression.core.bundle.Bundle;
+import org.apache.falcon.regression.core.helpers.ColoHelper;
+import org.apache.falcon.regression.core.util.*;
+import org.apache.falcon.regression.testHelper.BaseUITestClass;
+import org.apache.falcon.regression.ui.search.EntityPage;
+import org.apache.falcon.regression.ui.search.InstancePage;
+import org.apache.falcon.regression.ui.search.LoginPage;
+import org.apache.falcon.regression.ui.search.SearchPage;
+import org.apache.falcon.resource.InstancesResult;
+import org.apache.oozie.client.CoordinatorAction;
+import org.apache.oozie.client.OozieClient;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.EnumSet;
+
+/**
+ * Tests for Search UI Instance Page.
+ */
+@Test(groups = "search-ui")
+public class InstancePageTest extends BaseUITestClass {
+
+ private final ColoHelper cluster = servers.get(0);
+ private final 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" + MINUTE_DATE_PATTERN;
+ private SearchPage searchPage;
+ private InstancePage instancePage;
+ private String instance = "2010-01-02T01:00Z";
+ private String processName;
+
+ @BeforeClass(alwaysRun = true)
+ public void setup() {
+ openBrowser();
+ searchPage = LoginPage.open(getDriver()).doDefaultLogin();
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public void submitEntities() throws Exception {
+ cleanAndGetTestDir();
+ HadoopUtil.uploadDir(serverFS.get(0), aggregateWorkflowDir, OSUtil.RESOURCES_OOZIE);
+ bundles[0] = BundleUtil.readELBundle();
+ bundles[0] = new Bundle(bundles[0], cluster);
+ bundles[0].generateUniqueBundle(this);
+ bundles[0].setInputFeedDataPath(feedInputPath);
+ bundles[0].setProcessWorkflow(aggregateWorkflowDir);
+ bundles[0].setProcessValidity("2010-01-02T01:00Z", "2010-01-02T01:01Z");
+ bundles[0].setProcessInputStartEnd("now(0, 0)", "now(0, 0)");
+ bundles[0].setProcessPeriodicity(5, Frequency.TimeUnit.minutes);
+ bundles[0].setOutputFeedPeriodicity(5, Frequency.TimeUnit.minutes);
+ bundles[0].setOutputFeedLocationData(feedOutputPath);
+ bundles[0].submitAndScheduleProcess();
+ processName = bundles[0].getProcessName();
+ searchPage.refresh();
+ InstanceUtil.waitTillInstanceReachState(clusterOC, processName, 1,
+ CoordinatorAction.Status.WAITING, EntityType.PROCESS, 5);
+ }
+
+ @Test
+ public void testInstancePageStatusWaitingRunning() throws Exception {
+ instancePage = searchPage.openEntityPage(processName).openInstance(instance);
+ checkInstanceStatuses(InstancesResult.WorkflowStatus.WAITING);
+
+ Assert.assertEquals(instancePage.getButtons(false), EnumSet.allOf(InstancePage.Button.class),
+ "All buttons should be disabled for WAITING instance");
+
+ OozieUtil.createMissingDependencies(cluster, EntityType.PROCESS, processName, 0);
+
+ InstanceUtil.waitTillInstanceReachState(clusterOC, processName, 1,
+ CoordinatorAction.Status.RUNNING, EntityType.PROCESS, 5);
+
+ instancePage = instancePage.refreshPage();
+ checkInstanceStatuses(InstancesResult.WorkflowStatus.RUNNING);
+ Assert.assertEquals(instancePage.getButtons(false), EnumSet.of(InstancePage.Button.Resume),
+ "Only 'Resume' button should be disabled for RUNNING instance");
+ }
+
+ @Test
+ public void testInstancePagePauseResume() throws Exception {
+ OozieUtil.createMissingDependencies(cluster, EntityType.PROCESS, processName, 0);
+ InstanceUtil.waitTillInstanceReachState(clusterOC, processName, 1,
+ CoordinatorAction.Status.RUNNING, EntityType.PROCESS, 5);
+
+ instancePage = searchPage.openEntityPage(processName).openInstance(instance);
+ checkInstanceStatuses(InstancesResult.WorkflowStatus.RUNNING);
+
+ instancePage.clickButton(InstancePage.Button.Suspend);
+ checkInstanceStatuses(InstancesResult.WorkflowStatus.SUSPENDED);
+
+ Assert.assertEquals(instancePage.getButtons(false), EnumSet.of(InstancePage.Button.Suspend),
+ "Only 'Suspend' button should be disabled for SUSPENDED instance");
+
+ instancePage.clickButton(InstancePage.Button.Resume);
+ checkInstanceStatuses(InstancesResult.WorkflowStatus.RUNNING);
+ }
+
+ @Test
+ public void testInstancePageKillRerun() throws Exception {
+ OozieUtil.createMissingDependencies(cluster, EntityType.PROCESS, processName, 0);
+ InstanceUtil.waitTillInstanceReachState(clusterOC, processName, 1,
+ CoordinatorAction.Status.RUNNING, EntityType.PROCESS, 5);
+
+ instancePage = searchPage.openEntityPage(processName).openInstance(instance);
+ checkInstanceStatuses(InstancesResult.WorkflowStatus.RUNNING);
+
+ instancePage.clickButton(InstancePage.Button.Stop);
+ checkInstanceStatuses(InstancesResult.WorkflowStatus.KILLED);
+
+ Assert.assertEquals(instancePage.getButtons(true), EnumSet.of(InstancePage.Button.Resume),
+ "Only 'Resume' button should be active for KILLED instance");
+
+ instancePage.clickButton(InstancePage.Button.Resume);
+ checkInstanceStatuses(InstancesResult.WorkflowStatus.RUNNING);
+ }
+
+ @Test
+ public void testInstancePageInfo() throws Exception {
+ OozieUtil.createMissingDependencies(cluster, EntityType.PROCESS, processName, 0);
+ InstanceUtil.waitTillInstanceReachState(clusterOC, processName, 1,
+ CoordinatorAction.Status.SUCCEEDED, EntityType.PROCESS, 5);
+
+ EntityPage entityPage = searchPage.openEntityPage(processName);
+ EntityPage.OneInstanceSummary summary = EntityPage.InstanceSummary
+ .getOneSummary(entityPage.getInstanceSummary().getSummary(), instance);
+ Assert.assertNotNull(summary, "Instance not found on entity page");
+ Assert.assertEquals(summary.getStatus(), "SUCCEEDED", "Unexpected status on entity page");
+
+ instancePage = entityPage.openInstance(instance);
+ checkInstanceStatuses(InstancesResult.WorkflowStatus.SUCCEEDED);
+
+ Assert.assertEquals(instancePage.getEntityName(), processName, "Process name isn't shown correctly");
+
+ Assert.assertTrue(instancePage.isLineagePresent(), "Lineage graph should be present");
+ }
+
+ @Test
+ public void testHeader() {
+ instancePage = searchPage.openEntityPage(processName).openInstance(instance);
+ instancePage.getPageHeader().checkHeader();
+
+ }
+
+
+ private void checkInstanceStatuses(InstancesResult.WorkflowStatus status) throws Exception {
+ InstancesResult.Instance[] instances = prism.getProcessHelper()
+ .listInstances(processName, "start=" + instance, null).getInstances();
+ Assert.assertNotNull(instance, "Instances not found via API");
+ Assert.assertEquals(instances.length, 1, "Only one instance expected via API");
+ Assert.assertEquals(instances[0].getStatus(), status, "Unexpected status via API");
+
+ Assert.assertEquals(instancePage.getStatus(), status.toString(), "Unexpected status on UI");
+ }
+
+
+ @AfterMethod(alwaysRun = true)
+ public void tearDown() throws IOException {
+ removeTestClassEntities();
+ }
+
+ @AfterClass(alwaysRun = true)
+ public void tearDownClass() {
+ closeBrowser();
+ }
+}