HADOOP-6222. Core doesn't have TestCommonCLI facility. Contributed by Konstantin Boudnik.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@890964 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7a9ec5d90b
commit
e8d9bf47ab
|
@ -61,6 +61,8 @@ Trunk (unreleased changes)
|
|||
|
||||
HADOOP-6413. Move TestReflectionUtils to Common. (Todd Lipcon via tomwhite)
|
||||
|
||||
HADOOP-6222. Core doesn't have TestCommonCLI facility. (cos)
|
||||
|
||||
OPTIMIZATIONS
|
||||
|
||||
BUG FIXES
|
||||
|
|
|
@ -0,0 +1,450 @@
|
|||
/**
|
||||
* 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.hadoop.cli;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.hadoop.cli.util.CLITestData;
|
||||
import org.apache.hadoop.cli.util.CLITestData.TestCmd;
|
||||
import org.apache.hadoop.cli.util.CLITestData.TestCmd.CommandType;
|
||||
import org.apache.hadoop.cli.util.CommandExecutor;
|
||||
import org.apache.hadoop.cli.util.CommandExecutor.Result;
|
||||
import org.apache.hadoop.cli.util.ComparatorBase;
|
||||
import org.apache.hadoop.cli.util.ComparatorData;
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.security.authorize.ServiceAuthorizationManager;
|
||||
import org.apache.hadoop.util.StringUtils;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Tests for the Command Line Interface (CLI)
|
||||
*/
|
||||
public class CLITestHelper {
|
||||
private static final Log LOG =
|
||||
LogFactory.getLog(CLITestHelper.class.getName());
|
||||
|
||||
// In this mode, it runs the command and compares the actual output
|
||||
// with the expected output
|
||||
public static final String TESTMODE_TEST = "test"; // Run the tests
|
||||
|
||||
// If it is set to nocompare, run the command and do not compare.
|
||||
// This can be useful populate the testConfig.xml file the first time
|
||||
// a new command is added
|
||||
public static final String TESTMODE_NOCOMPARE = "nocompare";
|
||||
public static final String TEST_CACHE_DATA_DIR =
|
||||
System.getProperty("test.cache.data", "build/test/cache");
|
||||
|
||||
//By default, run the tests. The other mode is to run the commands and not
|
||||
// compare the output
|
||||
protected String testMode = TESTMODE_TEST;
|
||||
|
||||
// Storage for tests read in from the config file
|
||||
protected ArrayList<CLITestData> testsFromConfigFile = null;
|
||||
protected ArrayList<ComparatorData> testComparators = null;
|
||||
protected String thisTestCaseName = null;
|
||||
protected ComparatorData comparatorData = null;
|
||||
protected Configuration conf = null;
|
||||
protected String clitestDataDir = null;
|
||||
protected String username = null;
|
||||
|
||||
/**
|
||||
* Read the test config file - testConfig.xml
|
||||
*/
|
||||
protected void readTestConfigFile() {
|
||||
String testConfigFile = getTestFile();
|
||||
if (testsFromConfigFile == null) {
|
||||
boolean success = false;
|
||||
testConfigFile = TEST_CACHE_DATA_DIR + File.separator + testConfigFile;
|
||||
try {
|
||||
SAXParser p = (SAXParserFactory.newInstance()).newSAXParser();
|
||||
p.parse(testConfigFile, new TestConfigFileParser());
|
||||
success = true;
|
||||
} catch (Exception e) {
|
||||
LOG.info("File: " + testConfigFile + " not found");
|
||||
success = false;
|
||||
}
|
||||
assertTrue("Error reading test config file", success);
|
||||
}
|
||||
}
|
||||
|
||||
protected String getTestFile() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup
|
||||
*/
|
||||
public void setUp() throws Exception {
|
||||
// Read the testConfig.xml file
|
||||
readTestConfigFile();
|
||||
|
||||
conf = new Configuration();
|
||||
conf.setBoolean(ServiceAuthorizationManager.SERVICE_AUTHORIZATION_CONFIG,
|
||||
true);
|
||||
|
||||
clitestDataDir = new File(TEST_CACHE_DATA_DIR).
|
||||
toURI().toString().replace(' ', '+');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tear down
|
||||
*/
|
||||
public void tearDown() throws Exception {
|
||||
displayResults();
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand the commands from the test config xml file
|
||||
* @param cmd
|
||||
* @return String expanded command
|
||||
*/
|
||||
protected String expandCommand(final String cmd) {
|
||||
String expCmd = cmd;
|
||||
expCmd = expCmd.replaceAll("CLITEST_DATA", clitestDataDir);
|
||||
expCmd = expCmd.replaceAll("USERNAME", username);
|
||||
|
||||
return expCmd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the summarized results
|
||||
*/
|
||||
private void displayResults() {
|
||||
LOG.info("Detailed results:");
|
||||
LOG.info("----------------------------------\n");
|
||||
|
||||
for (int i = 0; i < testsFromConfigFile.size(); i++) {
|
||||
CLITestData td = testsFromConfigFile.get(i);
|
||||
|
||||
boolean testResult = td.getTestResult();
|
||||
|
||||
// Display the details only if there is a failure
|
||||
if (!testResult) {
|
||||
LOG.info("-------------------------------------------");
|
||||
LOG.info(" Test ID: [" + (i + 1) + "]");
|
||||
LOG.info(" Test Description: [" + td.getTestDesc() + "]");
|
||||
LOG.info("");
|
||||
|
||||
ArrayList<TestCmd> testCommands = td.getTestCommands();
|
||||
for (TestCmd cmd : testCommands) {
|
||||
LOG.info(" Test Commands: [" +
|
||||
expandCommand(cmd.getCmd()) + "]");
|
||||
}
|
||||
|
||||
LOG.info("");
|
||||
ArrayList<TestCmd> cleanupCommands = td.getCleanupCommands();
|
||||
for (TestCmd cmd : cleanupCommands) {
|
||||
LOG.info(" Cleanup Commands: [" +
|
||||
expandCommand(cmd.getCmd()) + "]");
|
||||
}
|
||||
|
||||
LOG.info("");
|
||||
ArrayList<ComparatorData> compdata = td.getComparatorData();
|
||||
for (ComparatorData cd : compdata) {
|
||||
boolean resultBoolean = cd.getTestResult();
|
||||
LOG.info(" Comparator: [" +
|
||||
cd.getComparatorType() + "]");
|
||||
LOG.info(" Comparision result: [" +
|
||||
(resultBoolean ? "pass" : "fail") + "]");
|
||||
LOG.info(" Expected output: [" +
|
||||
cd.getExpectedOutput() + "]");
|
||||
LOG.info(" Actual output: [" +
|
||||
cd.getActualOutput() + "]");
|
||||
}
|
||||
LOG.info("");
|
||||
}
|
||||
}
|
||||
|
||||
LOG.info("Summary results:");
|
||||
LOG.info("----------------------------------\n");
|
||||
|
||||
boolean overallResults = true;
|
||||
int totalPass = 0;
|
||||
int totalFail = 0;
|
||||
int totalComparators = 0;
|
||||
for (int i = 0; i < testsFromConfigFile.size(); i++) {
|
||||
CLITestData td = testsFromConfigFile.get(i);
|
||||
totalComparators +=
|
||||
testsFromConfigFile.get(i).getComparatorData().size();
|
||||
boolean resultBoolean = td.getTestResult();
|
||||
if (resultBoolean) {
|
||||
totalPass ++;
|
||||
} else {
|
||||
totalFail ++;
|
||||
}
|
||||
overallResults &= resultBoolean;
|
||||
}
|
||||
|
||||
|
||||
LOG.info(" Testing mode: " + testMode);
|
||||
LOG.info("");
|
||||
LOG.info(" Overall result: " +
|
||||
(overallResults ? "+++ PASS +++" : "--- FAIL ---"));
|
||||
if ((totalPass + totalFail) == 0) {
|
||||
LOG.info(" # Tests pass: " + 0);
|
||||
LOG.info(" # Tests fail: " + 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG.info(" # Tests pass: " + totalPass +
|
||||
" (" + (100 * totalPass / (totalPass + totalFail)) + "%)");
|
||||
LOG.info(" # Tests fail: " + totalFail +
|
||||
" (" + (100 * totalFail / (totalPass + totalFail)) + "%)");
|
||||
}
|
||||
|
||||
LOG.info(" # Validations done: " + totalComparators +
|
||||
" (each test may do multiple validations)");
|
||||
|
||||
LOG.info("");
|
||||
LOG.info("Failing tests:");
|
||||
LOG.info("--------------");
|
||||
int i = 0;
|
||||
boolean foundTests = false;
|
||||
for (i = 0; i < testsFromConfigFile.size(); i++) {
|
||||
boolean resultBoolean = testsFromConfigFile.get(i).getTestResult();
|
||||
if (!resultBoolean) {
|
||||
LOG.info((i + 1) + ": " +
|
||||
testsFromConfigFile.get(i).getTestDesc());
|
||||
foundTests = true;
|
||||
}
|
||||
}
|
||||
if (!foundTests) {
|
||||
LOG.info("NONE");
|
||||
}
|
||||
|
||||
foundTests = false;
|
||||
LOG.info("");
|
||||
LOG.info("Passing tests:");
|
||||
LOG.info("--------------");
|
||||
for (i = 0; i < testsFromConfigFile.size(); i++) {
|
||||
boolean resultBoolean = testsFromConfigFile.get(i).getTestResult();
|
||||
if (resultBoolean) {
|
||||
LOG.info((i + 1) + ": " +
|
||||
testsFromConfigFile.get(i).getTestDesc());
|
||||
foundTests = true;
|
||||
}
|
||||
}
|
||||
if (!foundTests) {
|
||||
LOG.info("NONE");
|
||||
}
|
||||
|
||||
assertTrue("One of the tests failed. " +
|
||||
"See the Detailed results to identify " +
|
||||
"the command that failed", overallResults);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the actual output with the expected output
|
||||
* @param compdata
|
||||
* @return
|
||||
*/
|
||||
private boolean compareTestOutput(ComparatorData compdata, Result cmdResult) {
|
||||
// Compare the output based on the comparator
|
||||
String comparatorType = compdata.getComparatorType();
|
||||
Class<?> comparatorClass = null;
|
||||
|
||||
// If testMode is "test", then run the command and compare the output
|
||||
// If testMode is "nocompare", then run the command and dump the output.
|
||||
// Do not compare
|
||||
|
||||
boolean compareOutput = false;
|
||||
|
||||
if (testMode.equals(TESTMODE_TEST)) {
|
||||
try {
|
||||
// Initialize the comparator class and run its compare method
|
||||
comparatorClass = Class.forName("org.apache.hadoop.cli.util." +
|
||||
comparatorType);
|
||||
ComparatorBase comp = (ComparatorBase) comparatorClass.newInstance();
|
||||
compareOutput = comp.compare(cmdResult.getCommandOutput(),
|
||||
compdata.getExpectedOutput());
|
||||
} catch (Exception e) {
|
||||
LOG.info("Error in instantiating the comparator" + e);
|
||||
}
|
||||
}
|
||||
|
||||
return compareOutput;
|
||||
}
|
||||
|
||||
/***********************************
|
||||
************* TESTS RUNNER
|
||||
*********************************/
|
||||
|
||||
public void testAll() {
|
||||
assertTrue("Number of tests has to be greater then zero",
|
||||
testsFromConfigFile.size() > 0);
|
||||
LOG.info("TestAll");
|
||||
// Run the tests defined in the testConf.xml config file.
|
||||
for (int index = 0; index < testsFromConfigFile.size(); index++) {
|
||||
|
||||
CLITestData testdata = (CLITestData) testsFromConfigFile.get(index);
|
||||
|
||||
// Execute the test commands
|
||||
ArrayList<TestCmd> testCommands = testdata.getTestCommands();
|
||||
Result cmdResult = null;
|
||||
for (TestCmd cmd : testCommands) {
|
||||
try {
|
||||
cmdResult = execute(cmd);
|
||||
} catch (Exception e) {
|
||||
fail(StringUtils.stringifyException(e));
|
||||
}
|
||||
}
|
||||
|
||||
boolean overallTCResult = true;
|
||||
// Run comparators
|
||||
ArrayList<ComparatorData> compdata = testdata.getComparatorData();
|
||||
for (ComparatorData cd : compdata) {
|
||||
final String comptype = cd.getComparatorType();
|
||||
|
||||
boolean compareOutput = false;
|
||||
|
||||
if (! comptype.equalsIgnoreCase("none")) {
|
||||
compareOutput = compareTestOutput(cd, cmdResult);
|
||||
overallTCResult &= compareOutput;
|
||||
}
|
||||
|
||||
cd.setExitCode(cmdResult.getExitCode());
|
||||
cd.setActualOutput(cmdResult.getCommandOutput());
|
||||
cd.setTestResult(compareOutput);
|
||||
}
|
||||
testdata.setTestResult(overallTCResult);
|
||||
|
||||
// Execute the cleanup commands
|
||||
ArrayList<TestCmd> cleanupCommands = testdata.getCleanupCommands();
|
||||
for (TestCmd cmd : cleanupCommands) {
|
||||
try {
|
||||
execute(cmd);
|
||||
} catch (Exception e) {
|
||||
fail(StringUtils.stringifyException(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected CommandExecutor.Result execute(TestCmd cmd) throws Exception {
|
||||
throw new Exception("Unknow type of Test command:"+ cmd.getType());
|
||||
}
|
||||
|
||||
/*
|
||||
* Parser class for the test config xml file
|
||||
*/
|
||||
class TestConfigFileParser extends DefaultHandler {
|
||||
String charString = null;
|
||||
CLITestData td = null;
|
||||
ArrayList<TestCmd> testCommands = null;
|
||||
ArrayList<TestCmd> cleanupCommands = null;
|
||||
|
||||
@Override
|
||||
public void startDocument() throws SAXException {
|
||||
testsFromConfigFile = new ArrayList<CLITestData>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startElement(String uri,
|
||||
String localName,
|
||||
String qName,
|
||||
Attributes attributes) throws SAXException {
|
||||
if (qName.equals("test")) {
|
||||
td = new CLITestData();
|
||||
} else if (qName.equals("test-commands")) {
|
||||
testCommands = new ArrayList<TestCmd>();
|
||||
} else if (qName.equals("cleanup-commands")) {
|
||||
cleanupCommands = new ArrayList<TestCmd>();
|
||||
} else if (qName.equals("comparators")) {
|
||||
testComparators = new ArrayList<ComparatorData>();
|
||||
} else if (qName.equals("comparator")) {
|
||||
comparatorData = new ComparatorData();
|
||||
}
|
||||
charString = "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(String uri,
|
||||
String localName,
|
||||
String qName) throws SAXException {
|
||||
if (qName.equals("description")) {
|
||||
td.setTestDesc(charString);
|
||||
} else if (qName.equals("test-commands")) {
|
||||
td.setTestCommands(testCommands);
|
||||
testCommands = null;
|
||||
} else if (qName.equals("cleanup-commands")) {
|
||||
td.setCleanupCommands(cleanupCommands);
|
||||
cleanupCommands = null;
|
||||
} else if (qName.equals("command")) {
|
||||
if (testCommands != null) {
|
||||
testCommands.add(new TestCmd(charString, CommandType.FS));
|
||||
} else if (cleanupCommands != null) {
|
||||
cleanupCommands.add(new TestCmd(charString, CommandType.FS));
|
||||
}
|
||||
} else if (qName.equals("dfs-admin-command")) {
|
||||
if (testCommands != null) {
|
||||
testCommands.add(new TestCmd(charString, CommandType.DFSADMIN));
|
||||
} else if (cleanupCommands != null) {
|
||||
cleanupCommands.add(new TestCmd(charString, CommandType.DFSADMIN));
|
||||
}
|
||||
} else if (qName.equals("mr-admin-command")) {
|
||||
if (testCommands != null) {
|
||||
testCommands.add(new TestCmd(charString, CommandType.MRADMIN));
|
||||
} else if (cleanupCommands != null) {
|
||||
cleanupCommands.add(new TestCmd(charString, CommandType.MRADMIN));
|
||||
}
|
||||
} else if (qName.equals("archive-command")) {
|
||||
if (testCommands != null) {
|
||||
testCommands.add(new TestCmd(charString, CommandType.ARCHIVE));
|
||||
} else if (cleanupCommands != null) {
|
||||
cleanupCommands.add(new TestCmd(charString, CommandType.ARCHIVE));
|
||||
}
|
||||
} else if (qName.equals("comparators")) {
|
||||
td.setComparatorData(testComparators);
|
||||
} else if (qName.equals("comparator")) {
|
||||
testComparators.add(comparatorData);
|
||||
} else if (qName.equals("type")) {
|
||||
comparatorData.setComparatorType(charString);
|
||||
} else if (qName.equals("expected-output")) {
|
||||
comparatorData.setExpectedOutput(charString);
|
||||
} else if (qName.equals("test")) {
|
||||
testsFromConfigFile.add(td);
|
||||
td = null;
|
||||
} else if (qName.equals("mode")) {
|
||||
testMode = charString;
|
||||
if (!testMode.equals(TESTMODE_NOCOMPARE) &&
|
||||
!testMode.equals(TESTMODE_TEST)) {
|
||||
testMode = TESTMODE_TEST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void characters(char[] ch,
|
||||
int start,
|
||||
int length) throws SAXException {
|
||||
String s = new String(ch, start, length);
|
||||
charString += s;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,433 +18,42 @@
|
|||
|
||||
package org.apache.hadoop.cli;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.hadoop.cli.util.CLITestData;
|
||||
import org.apache.hadoop.cli.util.CmdFactory;
|
||||
import org.apache.hadoop.cli.util.CommandExecutor;
|
||||
import org.apache.hadoop.cli.util.ComparatorBase;
|
||||
import org.apache.hadoop.cli.util.ComparatorData;
|
||||
import org.apache.hadoop.cli.util.CLITestData.TestCmd;
|
||||
import org.apache.hadoop.cli.util.CLITestData.TestCmd.CommandType;
|
||||
import org.apache.hadoop.cli.util.CommandExecutor.Result;
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.security.authorize.ServiceAuthorizationManager;
|
||||
import org.apache.hadoop.util.StringUtils;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests for the Command Line Interface (CLI)
|
||||
*/
|
||||
public class TestCLI extends TestCase {
|
||||
private static final Log LOG =
|
||||
LogFactory.getLog(TestCLI.class.getName());
|
||||
|
||||
// In this mode, it runs the command and compares the actual output
|
||||
// with the expected output
|
||||
public static final String TESTMODE_TEST = "test"; // Run the tests
|
||||
|
||||
// If it is set to nocompare, run the command and do not compare.
|
||||
// This can be useful populate the testConfig.xml file the first time
|
||||
// a new command is added
|
||||
public static final String TESTMODE_NOCOMPARE = "nocompare";
|
||||
public static final String TEST_CACHE_DATA_DIR =
|
||||
System.getProperty("test.cache.data", "build/test/cache");
|
||||
|
||||
//By default, run the tests. The other mode is to run the commands and not
|
||||
// compare the output
|
||||
protected String testMode = TESTMODE_TEST;
|
||||
|
||||
// Storage for tests read in from the config file
|
||||
protected ArrayList<CLITestData> testsFromConfigFile = null;
|
||||
protected ArrayList<ComparatorData> testComparators = null;
|
||||
protected String thisTestCaseName = null;
|
||||
protected ComparatorData comparatorData = null;
|
||||
protected Configuration conf = null;
|
||||
protected String clitestDataDir = null;
|
||||
protected String username = null;
|
||||
|
||||
/**
|
||||
* Read the test config file - testConfig.xml
|
||||
*/
|
||||
protected void readTestConfigFile() {
|
||||
String testConfigFile = getTestFile();
|
||||
if (testsFromConfigFile == null) {
|
||||
boolean success = false;
|
||||
testConfigFile = TEST_CACHE_DATA_DIR + File.separator + testConfigFile;
|
||||
try {
|
||||
SAXParser p = (SAXParserFactory.newInstance()).newSAXParser();
|
||||
p.parse(testConfigFile, new TestConfigFileParser());
|
||||
success = true;
|
||||
} catch (Exception e) {
|
||||
LOG.info("File: " + testConfigFile + " not found");
|
||||
success = false;
|
||||
}
|
||||
assertTrue("Error reading test config file", success);
|
||||
}
|
||||
public class TestCLI extends CLITestHelper {
|
||||
@Before
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@After
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CommandExecutor.Result execute(CLITestData.TestCmd cmd) throws Exception {
|
||||
return CmdFactory.getCommandExecutor(cmd, "").executeCommand(cmd.getCmd());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestFile() {
|
||||
return "testConf.xml";
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup
|
||||
*/
|
||||
public void setUp() throws Exception {
|
||||
// Read the testConfig.xml file
|
||||
readTestConfigFile();
|
||||
|
||||
conf = new Configuration();
|
||||
conf.setBoolean(ServiceAuthorizationManager.SERVICE_AUTHORIZATION_CONFIG,
|
||||
true);
|
||||
|
||||
clitestDataDir = new File(TEST_CACHE_DATA_DIR).
|
||||
toURI().toString().replace(' ', '+');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tear down
|
||||
*/
|
||||
public void tearDown() throws Exception {
|
||||
displayResults();
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand the commands from the test config xml file
|
||||
* @param cmd
|
||||
* @return String expanded command
|
||||
*/
|
||||
protected String expandCommand(final String cmd) {
|
||||
String expCmd = cmd;
|
||||
expCmd = expCmd.replaceAll("CLITEST_DATA", clitestDataDir);
|
||||
expCmd = expCmd.replaceAll("USERNAME", username);
|
||||
|
||||
return expCmd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the summarized results
|
||||
*/
|
||||
private void displayResults() {
|
||||
LOG.info("Detailed results:");
|
||||
LOG.info("----------------------------------\n");
|
||||
|
||||
for (int i = 0; i < testsFromConfigFile.size(); i++) {
|
||||
CLITestData td = testsFromConfigFile.get(i);
|
||||
|
||||
boolean testResult = td.getTestResult();
|
||||
|
||||
// Display the details only if there is a failure
|
||||
if (!testResult) {
|
||||
LOG.info("-------------------------------------------");
|
||||
LOG.info(" Test ID: [" + (i + 1) + "]");
|
||||
LOG.info(" Test Description: [" + td.getTestDesc() + "]");
|
||||
LOG.info("");
|
||||
|
||||
ArrayList<TestCmd> testCommands = td.getTestCommands();
|
||||
for (TestCmd cmd : testCommands) {
|
||||
LOG.info(" Test Commands: [" +
|
||||
expandCommand(cmd.getCmd()) + "]");
|
||||
}
|
||||
|
||||
LOG.info("");
|
||||
ArrayList<TestCmd> cleanupCommands = td.getCleanupCommands();
|
||||
for (TestCmd cmd : cleanupCommands) {
|
||||
LOG.info(" Cleanup Commands: [" +
|
||||
expandCommand(cmd.getCmd()) + "]");
|
||||
}
|
||||
|
||||
LOG.info("");
|
||||
ArrayList<ComparatorData> compdata = td.getComparatorData();
|
||||
for (ComparatorData cd : compdata) {
|
||||
boolean resultBoolean = cd.getTestResult();
|
||||
LOG.info(" Comparator: [" +
|
||||
cd.getComparatorType() + "]");
|
||||
LOG.info(" Comparision result: [" +
|
||||
(resultBoolean ? "pass" : "fail") + "]");
|
||||
LOG.info(" Expected output: [" +
|
||||
cd.getExpectedOutput() + "]");
|
||||
LOG.info(" Actual output: [" +
|
||||
cd.getActualOutput() + "]");
|
||||
}
|
||||
LOG.info("");
|
||||
}
|
||||
}
|
||||
|
||||
LOG.info("Summary results:");
|
||||
LOG.info("----------------------------------\n");
|
||||
|
||||
boolean overallResults = true;
|
||||
int totalPass = 0;
|
||||
int totalFail = 0;
|
||||
int totalComparators = 0;
|
||||
for (int i = 0; i < testsFromConfigFile.size(); i++) {
|
||||
CLITestData td = testsFromConfigFile.get(i);
|
||||
totalComparators +=
|
||||
testsFromConfigFile.get(i).getComparatorData().size();
|
||||
boolean resultBoolean = td.getTestResult();
|
||||
if (resultBoolean) {
|
||||
totalPass ++;
|
||||
} else {
|
||||
totalFail ++;
|
||||
}
|
||||
overallResults &= resultBoolean;
|
||||
}
|
||||
|
||||
|
||||
LOG.info(" Testing mode: " + testMode);
|
||||
LOG.info("");
|
||||
LOG.info(" Overall result: " +
|
||||
(overallResults ? "+++ PASS +++" : "--- FAIL ---"));
|
||||
if ((totalPass + totalFail) == 0) {
|
||||
LOG.info(" # Tests pass: " + 0);
|
||||
LOG.info(" # Tests fail: " + 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG.info(" # Tests pass: " + totalPass +
|
||||
" (" + (100 * totalPass / (totalPass + totalFail)) + "%)");
|
||||
LOG.info(" # Tests fail: " + totalFail +
|
||||
" (" + (100 * totalFail / (totalPass + totalFail)) + "%)");
|
||||
}
|
||||
|
||||
LOG.info(" # Validations done: " + totalComparators +
|
||||
" (each test may do multiple validations)");
|
||||
|
||||
LOG.info("");
|
||||
LOG.info("Failing tests:");
|
||||
LOG.info("--------------");
|
||||
int i = 0;
|
||||
boolean foundTests = false;
|
||||
for (i = 0; i < testsFromConfigFile.size(); i++) {
|
||||
boolean resultBoolean = testsFromConfigFile.get(i).getTestResult();
|
||||
if (!resultBoolean) {
|
||||
LOG.info((i + 1) + ": " +
|
||||
testsFromConfigFile.get(i).getTestDesc());
|
||||
foundTests = true;
|
||||
}
|
||||
}
|
||||
if (!foundTests) {
|
||||
LOG.info("NONE");
|
||||
}
|
||||
|
||||
foundTests = false;
|
||||
LOG.info("");
|
||||
LOG.info("Passing tests:");
|
||||
LOG.info("--------------");
|
||||
for (i = 0; i < testsFromConfigFile.size(); i++) {
|
||||
boolean resultBoolean = testsFromConfigFile.get(i).getTestResult();
|
||||
if (resultBoolean) {
|
||||
LOG.info((i + 1) + ": " +
|
||||
testsFromConfigFile.get(i).getTestDesc());
|
||||
foundTests = true;
|
||||
}
|
||||
}
|
||||
if (!foundTests) {
|
||||
LOG.info("NONE");
|
||||
}
|
||||
|
||||
assertTrue("One of the tests failed. " +
|
||||
"See the Detailed results to identify " +
|
||||
"the command that failed", overallResults);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the actual output with the expected output
|
||||
* @param compdata
|
||||
* @return
|
||||
*/
|
||||
private boolean compareTestOutput(ComparatorData compdata, Result cmdResult) {
|
||||
// Compare the output based on the comparator
|
||||
String comparatorType = compdata.getComparatorType();
|
||||
Class<?> comparatorClass = null;
|
||||
|
||||
// If testMode is "test", then run the command and compare the output
|
||||
// If testMode is "nocompare", then run the command and dump the output.
|
||||
// Do not compare
|
||||
|
||||
boolean compareOutput = false;
|
||||
|
||||
if (testMode.equals(TESTMODE_TEST)) {
|
||||
try {
|
||||
// Initialize the comparator class and run its compare method
|
||||
comparatorClass = Class.forName("org.apache.hadoop.cli.util." +
|
||||
comparatorType);
|
||||
ComparatorBase comp = (ComparatorBase) comparatorClass.newInstance();
|
||||
compareOutput = comp.compare(cmdResult.getCommandOutput(),
|
||||
compdata.getExpectedOutput());
|
||||
} catch (Exception e) {
|
||||
LOG.info("Error in instantiating the comparator" + e);
|
||||
}
|
||||
}
|
||||
|
||||
return compareOutput;
|
||||
}
|
||||
|
||||
/***********************************
|
||||
************* TESTS
|
||||
*********************************/
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testAll() {
|
||||
LOG.info("TestAll");
|
||||
|
||||
// Run the tests defined in the testConf.xml config file.
|
||||
for (int index = 0; index < testsFromConfigFile.size(); index++) {
|
||||
|
||||
CLITestData testdata = (CLITestData) testsFromConfigFile.get(index);
|
||||
|
||||
// Execute the test commands
|
||||
ArrayList<TestCmd> testCommands = testdata.getTestCommands();
|
||||
Result cmdResult = null;
|
||||
for (TestCmd cmd : testCommands) {
|
||||
try {
|
||||
cmdResult = execute(cmd);
|
||||
} catch (Exception e) {
|
||||
fail(StringUtils.stringifyException(e));
|
||||
}
|
||||
}
|
||||
|
||||
boolean overallTCResult = true;
|
||||
// Run comparators
|
||||
ArrayList<ComparatorData> compdata = testdata.getComparatorData();
|
||||
for (ComparatorData cd : compdata) {
|
||||
final String comptype = cd.getComparatorType();
|
||||
|
||||
boolean compareOutput = false;
|
||||
|
||||
if (! comptype.equalsIgnoreCase("none")) {
|
||||
compareOutput = compareTestOutput(cd, cmdResult);
|
||||
overallTCResult &= compareOutput;
|
||||
}
|
||||
|
||||
cd.setExitCode(cmdResult.getExitCode());
|
||||
cd.setActualOutput(cmdResult.getCommandOutput());
|
||||
cd.setTestResult(compareOutput);
|
||||
}
|
||||
testdata.setTestResult(overallTCResult);
|
||||
|
||||
// Execute the cleanup commands
|
||||
ArrayList<TestCmd> cleanupCommands = testdata.getCleanupCommands();
|
||||
for (TestCmd cmd : cleanupCommands) {
|
||||
try {
|
||||
execute(cmd);
|
||||
} catch (Exception e) {
|
||||
fail(StringUtils.stringifyException(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected CommandExecutor.Result execute(TestCmd cmd) throws Exception {
|
||||
throw new Exception("Unknow type of Test command:"+ cmd.getType());
|
||||
}
|
||||
|
||||
/*
|
||||
* Parser class for the test config xml file
|
||||
*/
|
||||
class TestConfigFileParser extends DefaultHandler {
|
||||
String charString = null;
|
||||
CLITestData td = null;
|
||||
ArrayList<TestCmd> testCommands = null;
|
||||
ArrayList<TestCmd> cleanupCommands = null;
|
||||
|
||||
@Override
|
||||
public void startDocument() throws SAXException {
|
||||
testsFromConfigFile = new ArrayList<CLITestData>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startElement(String uri,
|
||||
String localName,
|
||||
String qName,
|
||||
Attributes attributes) throws SAXException {
|
||||
if (qName.equals("test")) {
|
||||
td = new CLITestData();
|
||||
} else if (qName.equals("test-commands")) {
|
||||
testCommands = new ArrayList<TestCmd>();
|
||||
} else if (qName.equals("cleanup-commands")) {
|
||||
cleanupCommands = new ArrayList<TestCmd>();
|
||||
} else if (qName.equals("comparators")) {
|
||||
testComparators = new ArrayList<ComparatorData>();
|
||||
} else if (qName.equals("comparator")) {
|
||||
comparatorData = new ComparatorData();
|
||||
}
|
||||
charString = "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(String uri,
|
||||
String localName,
|
||||
String qName) throws SAXException {
|
||||
if (qName.equals("description")) {
|
||||
td.setTestDesc(charString);
|
||||
} else if (qName.equals("test-commands")) {
|
||||
td.setTestCommands(testCommands);
|
||||
testCommands = null;
|
||||
} else if (qName.equals("cleanup-commands")) {
|
||||
td.setCleanupCommands(cleanupCommands);
|
||||
cleanupCommands = null;
|
||||
} else if (qName.equals("command")) {
|
||||
if (testCommands != null) {
|
||||
testCommands.add(new TestCmd(charString, CommandType.FS));
|
||||
} else if (cleanupCommands != null) {
|
||||
cleanupCommands.add(new TestCmd(charString, CommandType.FS));
|
||||
}
|
||||
} else if (qName.equals("dfs-admin-command")) {
|
||||
if (testCommands != null) {
|
||||
testCommands.add(new TestCmd(charString, CommandType.DFSADMIN));
|
||||
} else if (cleanupCommands != null) {
|
||||
cleanupCommands.add(new TestCmd(charString, CommandType.DFSADMIN));
|
||||
}
|
||||
} else if (qName.equals("mr-admin-command")) {
|
||||
if (testCommands != null) {
|
||||
testCommands.add(new TestCmd(charString, CommandType.MRADMIN));
|
||||
} else if (cleanupCommands != null) {
|
||||
cleanupCommands.add(new TestCmd(charString, CommandType.MRADMIN));
|
||||
}
|
||||
} else if (qName.equals("archive-command")) {
|
||||
if (testCommands != null) {
|
||||
testCommands.add(new TestCmd(charString, CommandType.ARCHIVE));
|
||||
} else if (cleanupCommands != null) {
|
||||
cleanupCommands.add(new TestCmd(charString, CommandType.ARCHIVE));
|
||||
}
|
||||
} else if (qName.equals("comparators")) {
|
||||
td.setComparatorData(testComparators);
|
||||
} else if (qName.equals("comparator")) {
|
||||
testComparators.add(comparatorData);
|
||||
} else if (qName.equals("type")) {
|
||||
comparatorData.setComparatorType(charString);
|
||||
} else if (qName.equals("expected-output")) {
|
||||
comparatorData.setExpectedOutput(charString);
|
||||
} else if (qName.equals("test")) {
|
||||
testsFromConfigFile.add(td);
|
||||
td = null;
|
||||
} else if (qName.equals("mode")) {
|
||||
testMode = charString;
|
||||
if (!testMode.equals(TESTMODE_NOCOMPARE) &&
|
||||
!testMode.equals(TESTMODE_TEST)) {
|
||||
testMode = TESTMODE_TEST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void characters(char[] ch,
|
||||
int start,
|
||||
int length) throws SAXException {
|
||||
String s = new String(ch, start, length);
|
||||
charString += s;
|
||||
}
|
||||
super.testAll();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,21 @@
|
|||
TokenComparator
|
||||
-->
|
||||
<tests>
|
||||
<!-- Tests for help -->
|
||||
<test> <!-- TESTED -->
|
||||
<description>help: check if fs help message is shown</description>
|
||||
<test-commands>
|
||||
<command>-help</command>
|
||||
</test-commands>
|
||||
<cleanup-commands>
|
||||
</cleanup-commands>
|
||||
<comparators>
|
||||
<comparator>
|
||||
<type>SubstringComparator</type>
|
||||
<expected-output>hadoop fs is the command to execute fs commands. The full syntax is</expected-output>
|
||||
</comparator>
|
||||
</comparators>
|
||||
</test>
|
||||
|
||||
</tests>
|
||||
</configuration>
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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.hadoop.cli.util;
|
||||
|
||||
import org.apache.hadoop.fs.FsShell;
|
||||
import org.apache.hadoop.util.ToolRunner;
|
||||
|
||||
public class CLICommands {
|
||||
|
||||
public static class FSCmdExecutor extends CommandExecutor {
|
||||
protected String namenode = null;
|
||||
protected FsShell shell = null;
|
||||
|
||||
public FSCmdExecutor(String namenode, FsShell shell) {
|
||||
this.namenode = namenode;
|
||||
this.shell = shell;
|
||||
}
|
||||
|
||||
protected void execute(final String cmd) throws Exception{
|
||||
String[] args = getCommandAsArgs(cmd, "NAMENODE", this.namenode);
|
||||
ToolRunner.run(shell, args);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* 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.hadoop.cli.util;
|
||||
|
||||
import org.apache.hadoop.fs.FsShell;
|
||||
|
||||
public abstract class CmdFactory {
|
||||
public static CommandExecutor getCommandExecutor(CLITestData.TestCmd cmd,
|
||||
String tag)
|
||||
throws IllegalArgumentException {
|
||||
CommandExecutor executor = null;
|
||||
switch (cmd.getType()) {
|
||||
case FS:
|
||||
executor = new CLICommands.FSCmdExecutor(tag, new FsShell());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown type of Test command:" +
|
||||
cmd.getType());
|
||||
}
|
||||
return executor;
|
||||
}
|
||||
}
|
|
@ -18,13 +18,13 @@
|
|||
|
||||
package org.apache.hadoop.cli.util;
|
||||
|
||||
import org.apache.hadoop.cli.CLITestHelper;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.PrintStream;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.apache.hadoop.cli.TestCLI;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class execute commands and captures the output
|
||||
|
@ -41,7 +41,7 @@ public abstract class CommandExecutor {
|
|||
|
||||
args[i] = args[i].replaceAll(masterKey, master);
|
||||
args[i] = args[i].replaceAll("CLITEST_DATA",
|
||||
new File(TestCLI.TEST_CACHE_DATA_DIR).
|
||||
new File(CLITestHelper.TEST_CACHE_DATA_DIR).
|
||||
toURI().toString().replace(' ', '+'));
|
||||
args[i] = args[i].replaceAll("USERNAME", System.getProperty("user.name"));
|
||||
|
||||
|
|
Loading…
Reference in New Issue