/** * 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.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.falcon.regression.core.enumsAndConstants.MerlinConstants; import org.apache.falcon.regression.core.helpers.ColoHelper; import org.apache.falcon.regression.core.util.Config; import org.apache.falcon.regression.core.util.LogUtil; import org.apache.falcon.regression.core.util.OSUtil; import org.apache.falcon.regression.core.util.TimeUtil; import org.apache.falcon.regression.testHelper.BaseUITestClass; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.log4j.Logger; import org.apache.log4j.NDC; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.testng.IExecutionListener; import org.testng.ITestContext; import org.testng.ITestListener; import org.testng.ITestResult; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.Date; /** * Testng listener class. This is useful for things that are applicable to all the tests as well * taking actions that depend on test results. */ public class TestngListener implements ITestListener, IExecutionListener { private static final Logger LOGGER = Logger.getLogger(TestngListener.class); private final String hr = StringUtils.repeat("-", 100); private enum RunResult {SUCCESS, FAILED, SKIPPED, TestFailedButWithinSuccessPercentage } @Override public void onTestStart(ITestResult result) { LOGGER.info(hr); LOGGER.info( String.format("Testing going to start for: %s.%s(%s)", result.getTestClass().getName(), result.getName(), Arrays.toString(result.getParameters()))); NDC.push(result.getName()); } private void endOfTestHook(ITestResult result, RunResult outcome) { if (outcome != RunResult.SUCCESS) { try { takeScreenShot(result); } catch (Exception e) { LOGGER.info("Saving screenshot FAILED: " + e.getCause()); } } try { dumpFalconStore(result); } catch (Exception e) { LOGGER.info("Dumping of falcon store failed: " + e); } LOGGER.info( 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); } private void dumpFalconStore(ITestResult result) throws IOException { if (Config.getBoolean("merlin.dump.staging", false)) { final String[] serverNames = Config.getStringArray("servers"); for (final String serverName : serverNames) { final ColoHelper coloHelper = new ColoHelper(serverName.trim()); final FileSystem clusterFs = coloHelper.getClusterHelper().getHadoopFS(); final String fileNameTemp = StringUtils.join( new String[]{serverName, result.getName(), Arrays.toString(result.getParameters()), TimeUtil.dateToOozieDate(new Date()), }, "-"); final String localFileName = fileNameTemp.replaceAll(":", "-"); LOGGER.info("Dumping staging contents to: " + fileNameTemp); clusterFs.copyToLocalFile(false, new Path(MerlinConstants.STAGING_LOCATION), new Path(localFileName)); } } } @Override public void onTestSuccess(ITestResult result) { endOfTestHook(result, RunResult.SUCCESS); } @Override public void onTestFailure(ITestResult result) { endOfTestHook(result, RunResult.FAILED); LOGGER.info(ExceptionUtils.getStackTrace(result.getThrowable())); LOGGER.info(hr); } private void takeScreenShot(ITestResult result) throws IOException { String logs = Config.getProperty("log.capture.location", OSUtil.concat("target", "surefire-reports")); if (BaseUITestClass.getDriver() != null) { byte[] scrFile = ((TakesScreenshot)BaseUITestClass.getDriver()).getScreenshotAs(OutputType.BYTES); String params = Arrays.toString(result.getParameters()); params = params.replaceAll("[<>\":\\\\/\\|\\?\\*]", ""); //remove <>:"/\|?* String filename = OSUtil.concat(logs, "screenshots", String.format("%s.%s(%s).png", result.getTestClass().getRealClass().getSimpleName(), result.getName(), params)); LOGGER.info("Saving screenshot to: " + filename); FileUtils.writeByteArrayToFile(new File(filename), scrFile); } } @Override public void onTestSkipped(ITestResult result) { endOfTestHook(result, RunResult.SKIPPED); } @Override public void onTestFailedButWithinSuccessPercentage(ITestResult result) { endOfTestHook(result, RunResult.TestFailedButWithinSuccessPercentage); } @Override public void onStart(ITestContext context) { } @Override public void onFinish(ITestContext context) { } @Override public void onExecutionStart() { } @Override public void onExecutionFinish() { if (!Config.getBoolean("log.capture.oozie", false)) { LOGGER.info("oozie log capturing is disabled"); return; } final String logLocation = Config.getProperty("log.capture.location", "./"); final String[] serverNames = Config.getStringArray("servers"); for (final String serverName : serverNames) { final ColoHelper coloHelper = new ColoHelper(serverName.trim()); LogUtil.writeOozieLogs(coloHelper, logLocation); } } }