source: proiecte/HadoopJUnit/hadoop-0.20.1/src/test/org/apache/hadoop/cli/TestCLI.java @ 120

Last change on this file since 120 was 120, checked in by (none), 14 years ago

Added the mail files for the Hadoop JUNit Project

  • Property svn:executable set to *
File size: 16.1 KB
Line 
1/**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements.  See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership.  The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License.  You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19package org.apache.hadoop.cli;
20
21import java.io.File;
22import java.util.ArrayList;
23
24import javax.xml.parsers.SAXParser;
25import javax.xml.parsers.SAXParserFactory;
26
27import junit.framework.TestCase;
28
29import org.apache.commons.logging.Log;
30import org.apache.commons.logging.LogFactory;
31import org.apache.hadoop.cli.util.CLITestData;
32import org.apache.hadoop.cli.util.CommandExecutor;
33import org.apache.hadoop.cli.util.ComparatorBase;
34import org.apache.hadoop.cli.util.ComparatorData;
35import org.apache.hadoop.cli.util.CLITestData.TestCmd;
36import org.apache.hadoop.cli.util.CLITestData.TestCmd.CommandType;
37import org.apache.hadoop.conf.Configuration;
38import org.apache.hadoop.fs.FileSystem;
39import org.apache.hadoop.hdfs.DistributedFileSystem;
40import org.apache.hadoop.hdfs.MiniDFSCluster;
41import org.apache.hadoop.mapred.JobConf;
42import org.apache.hadoop.mapred.MiniMRCluster;
43import org.apache.hadoop.security.authorize.HadoopPolicyProvider;
44import org.apache.hadoop.security.authorize.PolicyProvider;
45import org.apache.hadoop.security.authorize.ServiceAuthorizationManager;
46import org.apache.hadoop.util.StringUtils;
47import org.xml.sax.Attributes;
48import org.xml.sax.SAXException;
49import org.xml.sax.helpers.DefaultHandler;
50
51/**
52 * Tests for the Command Line Interface (CLI)
53 */
54public class TestCLI extends TestCase {
55  private static final Log LOG =
56    LogFactory.getLog(TestCLI.class.getName());
57 
58  // In this mode, it runs the command and compares the actual output
59  // with the expected output 
60  public static final String TESTMODE_TEST = "test"; // Run the tests
61 
62  // If it is set to nocompare, run the command and do not compare.
63  // This can be useful populate the testConfig.xml file the first time
64  // a new command is added
65  public static final String TESTMODE_NOCOMPARE = "nocompare";
66  public static final String TEST_CACHE_DATA_DIR =
67    System.getProperty("test.cache.data", "build/test/cache");
68 
69  //By default, run the tests. The other mode is to run the commands and not
70  // compare the output
71  public static String testMode = TESTMODE_TEST;
72 
73  // Storage for tests read in from the config file
74  static ArrayList<CLITestData> testsFromConfigFile = null;
75  static ArrayList<ComparatorData> testComparators = null;
76  static String testConfigFile = "testConf.xml";
77  String thisTestCaseName = null;
78  static ComparatorData comparatorData = null;
79 
80  private static Configuration conf = null;
81  private static MiniDFSCluster dfsCluster = null;
82  private static DistributedFileSystem dfs = null;
83  private static MiniMRCluster mrCluster = null;
84  private static String namenode = null;
85  private static String jobtracker = null;
86  private static String clitestDataDir = null;
87  private static String username = null;
88 
89  /**
90   * Read the test config file - testConfig.xml
91   */
92  private void readTestConfigFile() {
93   
94    if (testsFromConfigFile == null) {
95      boolean success = false;
96      testConfigFile = TEST_CACHE_DATA_DIR + File.separator + testConfigFile;
97      try {
98        SAXParser p = (SAXParserFactory.newInstance()).newSAXParser();
99        p.parse(testConfigFile, new TestConfigFileParser());
100        success = true;
101      } catch (Exception e) {
102        LOG.info("File: " + testConfigFile + " not found");
103        success = false;
104      }
105      assertTrue("Error reading test config file", success);
106    }
107  }
108 
109  /*
110   * Setup
111   */
112  public void setUp() throws Exception {
113    // Read the testConfig.xml file
114    readTestConfigFile();
115   
116    // Start up the mini dfs cluster
117    boolean success = false;
118    conf = new Configuration();
119    conf.setClass(PolicyProvider.POLICY_PROVIDER_CONFIG,
120                  HadoopPolicyProvider.class, PolicyProvider.class);
121    conf.setBoolean(ServiceAuthorizationManager.SERVICE_AUTHORIZATION_CONFIG, 
122                    true);
123
124    dfsCluster = new MiniDFSCluster(conf, 1, true, null);
125    namenode = conf.get("fs.default.name", "file:///");
126    clitestDataDir = new File(TEST_CACHE_DATA_DIR).
127      toURI().toString().replace(' ', '+');
128    username = System.getProperty("user.name");
129
130    FileSystem fs = dfsCluster.getFileSystem();
131    assertTrue("Not a HDFS: "+fs.getUri(),
132               fs instanceof DistributedFileSystem);
133    dfs = (DistributedFileSystem) fs;
134   
135     // Start up mini mr cluster
136    JobConf mrConf = new JobConf(conf);
137    mrCluster = new MiniMRCluster(1, dfsCluster.getFileSystem().getUri().toString(), 1, 
138                           null, null, mrConf);
139    jobtracker = mrCluster.createJobConf().get("mapred.job.tracker", "local");
140
141    success = true;
142
143    assertTrue("Error setting up Mini DFS & MR clusters", success);
144  }
145 
146  /**
147   * Tear down
148   */
149  public void tearDown() throws Exception {
150    boolean success = false;
151    mrCluster.shutdown();
152   
153    dfs.close();
154    dfsCluster.shutdown();
155    success = true;
156    Thread.sleep(2000);
157
158    assertTrue("Error tearing down Mini DFS & MR clusters", success);
159   
160    displayResults();
161  }
162 
163  /**
164   * Expand the commands from the test config xml file
165   * @param cmd
166   * @return String expanded command
167   */
168  private String expandCommand(final String cmd) {
169    String expCmd = cmd;
170    expCmd = expCmd.replaceAll("NAMENODE", namenode);
171    expCmd = expCmd.replaceAll("JOBTRACKER", jobtracker);
172    expCmd = expCmd.replaceAll("CLITEST_DATA", clitestDataDir);
173    expCmd = expCmd.replaceAll("USERNAME", username);
174   
175    return expCmd;
176  }
177 
178  /**
179   * Display the summarized results
180   */
181  private void displayResults() {
182    LOG.info("Detailed results:");
183    LOG.info("----------------------------------\n");
184   
185    for (int i = 0; i < testsFromConfigFile.size(); i++) {
186      CLITestData td = testsFromConfigFile.get(i);
187     
188      boolean testResult = td.getTestResult();
189     
190      // Display the details only if there is a failure
191      if (!testResult) {
192        LOG.info("-------------------------------------------");
193        LOG.info("                    Test ID: [" + (i + 1) + "]");
194        LOG.info("           Test Description: [" + td.getTestDesc() + "]");
195        LOG.info("");
196
197        ArrayList<TestCmd> testCommands = td.getTestCommands();
198        for (TestCmd cmd : testCommands) {
199          LOG.info("              Test Commands: [" + 
200                   expandCommand(cmd.getCmd()) + "]");
201        }
202
203        LOG.info("");
204        ArrayList<TestCmd> cleanupCommands = td.getCleanupCommands();
205        for (TestCmd cmd : cleanupCommands) {
206          LOG.info("           Cleanup Commands: [" +
207                   expandCommand(cmd.getCmd()) + "]");
208        }
209
210        LOG.info("");
211        ArrayList<ComparatorData> compdata = td.getComparatorData();
212        for (ComparatorData cd : compdata) {
213          boolean resultBoolean = cd.getTestResult();
214          LOG.info("                 Comparator: [" + 
215                   cd.getComparatorType() + "]");
216          LOG.info("         Comparision result:   [" + 
217                   (resultBoolean ? "pass" : "fail") + "]");
218          LOG.info("            Expected output:   [" + 
219                   cd.getExpectedOutput() + "]");
220          LOG.info("              Actual output:   [" + 
221                   cd.getActualOutput() + "]");
222        }
223        LOG.info("");
224      }
225    }
226   
227    LOG.info("Summary results:");
228    LOG.info("----------------------------------\n");
229   
230    boolean overallResults = true;
231    int totalPass = 0;
232    int totalFail = 0;
233    int totalComparators = 0;
234    for (int i = 0; i < testsFromConfigFile.size(); i++) {
235      CLITestData td = testsFromConfigFile.get(i);
236      totalComparators += 
237          testsFromConfigFile.get(i).getComparatorData().size();
238      boolean resultBoolean = td.getTestResult();
239      if (resultBoolean) {
240        totalPass ++;
241      } else {
242        totalFail ++;
243      }
244      overallResults &= resultBoolean;
245    }
246   
247   
248    LOG.info("               Testing mode: " + testMode);
249    LOG.info("");
250    LOG.info("             Overall result: " + 
251                (overallResults ? "+++ PASS +++" : "--- FAIL ---"));
252    LOG.info("               # Tests pass: " + totalPass +
253                " (" + (100 * totalPass / (totalPass + totalFail)) + "%)");
254    LOG.info("               # Tests fail: " + totalFail + 
255                " (" + (100 * totalFail / (totalPass + totalFail)) + "%)");
256    LOG.info("         # Validations done: " + totalComparators + 
257                " (each test may do multiple validations)");
258   
259    LOG.info("");
260    LOG.info("Failing tests:");
261    LOG.info("--------------");
262    int i = 0;
263    boolean foundTests = false;
264    for (i = 0; i < testsFromConfigFile.size(); i++) {
265      boolean resultBoolean = testsFromConfigFile.get(i).getTestResult();
266      if (!resultBoolean) {
267        LOG.info((i + 1) + ": " + 
268                        testsFromConfigFile.get(i).getTestDesc());
269        foundTests = true;
270      }
271    }
272    if (!foundTests) {
273        LOG.info("NONE");
274    }
275   
276    foundTests = false;
277    LOG.info("");
278    LOG.info("Passing tests:");
279    LOG.info("--------------");
280    for (i = 0; i < testsFromConfigFile.size(); i++) {
281      boolean resultBoolean = testsFromConfigFile.get(i).getTestResult();
282      if (resultBoolean) {
283        LOG.info((i + 1) + ": " + 
284                        testsFromConfigFile.get(i).getTestDesc());
285        foundTests = true;
286      }
287    }
288    if (!foundTests) {
289        LOG.info("NONE");
290    }
291
292    assertTrue("One of the tests failed. " +
293                "See the Detailed results to identify " +
294                "the command that failed", overallResults);
295   
296  }
297 
298  /**
299   * Compare the actual output with the expected output
300   * @param compdata
301   * @return
302   */
303  private boolean compareTestOutput(ComparatorData compdata) {
304    // Compare the output based on the comparator
305    String comparatorType = compdata.getComparatorType();
306    Class<?> comparatorClass = null;
307   
308    // If testMode is "test", then run the command and compare the output
309    // If testMode is "nocompare", then run the command and dump the output.
310    // Do not compare
311   
312    boolean compareOutput = false;
313   
314    if (testMode.equals(TESTMODE_TEST)) {
315      try {
316        // Initialize the comparator class and run its compare method
317        comparatorClass = Class.forName("org.apache.hadoop.cli.util." + 
318          comparatorType);
319        ComparatorBase comp = (ComparatorBase) comparatorClass.newInstance();
320        compareOutput = comp.compare(CommandExecutor.getLastCommandOutput(), 
321          compdata.getExpectedOutput());
322      } catch (Exception e) {
323        LOG.info("Error in instantiating the comparator" + e);
324      }
325    }
326   
327    return compareOutput;
328  }
329 
330  /***********************************
331   ************* TESTS
332   *********************************/
333 
334  public void testAll() {
335    LOG.info("TestAll");
336   
337    // Run the tests defined in the testConf.xml config file.
338    for (int index = 0; index < testsFromConfigFile.size(); index++) {
339     
340      CLITestData testdata = (CLITestData) testsFromConfigFile.get(index);
341   
342      // Execute the test commands
343      ArrayList<TestCmd> testCommands = testdata.getTestCommands();
344      for (TestCmd cmd : testCommands) {
345      try {
346        CommandExecutor.executeCommand(cmd, namenode, jobtracker);
347      } catch (Exception e) {
348        fail(StringUtils.stringifyException(e));
349      }
350      }
351     
352      boolean overallTCResult = true;
353      // Run comparators
354      ArrayList<ComparatorData> compdata = testdata.getComparatorData();
355      for (ComparatorData cd : compdata) {
356        final String comptype = cd.getComparatorType();
357       
358        boolean compareOutput = false;
359       
360        if (! comptype.equalsIgnoreCase("none")) {
361          compareOutput = compareTestOutput(cd);
362          overallTCResult &= compareOutput;
363        }
364       
365        cd.setExitCode(CommandExecutor.getLastExitCode());
366        cd.setActualOutput(CommandExecutor.getLastCommandOutput());
367        cd.setTestResult(compareOutput);
368      }
369      testdata.setTestResult(overallTCResult);
370     
371      // Execute the cleanup commands
372      ArrayList<TestCmd> cleanupCommands = testdata.getCleanupCommands();
373      for (TestCmd cmd : cleanupCommands) {
374      try { 
375        CommandExecutor.executeCommand(cmd, namenode, jobtracker);
376      } catch (Exception e) {
377        fail(StringUtils.stringifyException(e));
378      }
379      }
380    }
381  }
382 
383  /*
384   * Parser class for the test config xml file
385   */
386  static class TestConfigFileParser extends DefaultHandler {
387    String charString = null;
388    CLITestData td = null;
389    ArrayList<TestCmd> testCommands = null;
390    ArrayList<TestCmd> cleanupCommands = null;
391   
392    @Override
393    public void startDocument() throws SAXException {
394      testsFromConfigFile = new ArrayList<CLITestData>();
395    }
396   
397    @Override
398    public void startElement(String uri, 
399                String localName, 
400                String qName, 
401                Attributes attributes) throws SAXException {
402      if (qName.equals("test")) {
403        td = new CLITestData();
404      } else if (qName.equals("test-commands")) {
405        testCommands = new ArrayList<TestCmd>();
406      } else if (qName.equals("cleanup-commands")) {
407        cleanupCommands = new ArrayList<TestCmd>();
408      } else if (qName.equals("comparators")) {
409        testComparators = new ArrayList<ComparatorData>();
410      } else if (qName.equals("comparator")) {
411        comparatorData = new ComparatorData();
412      }
413      charString = "";
414    }
415   
416    @Override
417    public void endElement(String uri, 
418                String localName, 
419                String qName) throws SAXException {
420      if (qName.equals("description")) {
421        td.setTestDesc(charString);
422      } else if (qName.equals("test-commands")) {
423        td.setTestCommands(testCommands);
424        testCommands = null;
425      } else if (qName.equals("cleanup-commands")) {
426        td.setCleanupCommands(cleanupCommands);
427        cleanupCommands = null;
428      } else if (qName.equals("command")) {
429        if (testCommands != null) {
430          testCommands.add(new TestCmd(charString, CommandType.FS));
431        } else if (cleanupCommands != null) {
432          cleanupCommands.add(new TestCmd(charString, CommandType.FS));
433        }
434      } else if (qName.equals("dfs-admin-command")) {
435          if (testCommands != null) {
436              testCommands.add(new TestCmd(charString,CommandType.DFSADMIN));
437            } else if (cleanupCommands != null) {
438              cleanupCommands.add(new TestCmd(charString, CommandType.DFSADMIN));
439            } 
440      } else if (qName.equals("mr-admin-command")) {
441        if (testCommands != null) {
442            testCommands.add(new TestCmd(charString,CommandType.MRADMIN));
443          } else if (cleanupCommands != null) {
444            cleanupCommands.add(new TestCmd(charString, CommandType.MRADMIN));
445          } 
446      } else if (qName.equals("comparators")) {
447        td.setComparatorData(testComparators);
448      } else if (qName.equals("comparator")) {
449        testComparators.add(comparatorData);
450      } else if (qName.equals("type")) {
451        comparatorData.setComparatorType(charString);
452      } else if (qName.equals("expected-output")) {
453        comparatorData.setExpectedOutput(charString);
454      } else if (qName.equals("test")) {
455        testsFromConfigFile.add(td);
456        td = null;
457      } else if (qName.equals("mode")) {
458        testMode = charString;
459        if (!testMode.equals(TESTMODE_NOCOMPARE) &&
460            !testMode.equals(TESTMODE_TEST)) {
461          testMode = TESTMODE_TEST;
462        }
463      }
464    }
465   
466    @Override
467    public void characters(char[] ch, 
468                int start, 
469                int length) throws SAXException {
470      String s = new String(ch, start, length);
471      charString += s;
472    }
473  }
474}
Note: See TracBrowser for help on using the repository browser.