/* * The MIT License * * Copyright (c) 2010 tap4j team (see AUTHORS) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.tap4j.perl; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.LinkedList; import java.util.List; import org.junit.Before; import org.junit.Test; import org.tap4j.model.Directive; import org.tap4j.model.Plan; import org.tap4j.model.TestResult; import org.tap4j.model.TestSet; import org.tap4j.producer.ProducerException; import org.tap4j.producer.TapProducer; import org.tap4j.util.DirectiveValues; import org.tap4j.util.StatusValues; /** * This class uses the awesome script created by Patrick LeBoutillier to test * TAP Streams generated with tap4j using Perl Test::Harness. This test is an * integration test, so by default it's disabled. In order to run this test, * execute mvn test -DintegrationTests=true. * * @since 1.4.6 */ public class TestPerlIntegration { private static final Integer SUCCESS_EXIT_CODE = Integer.valueOf(0); private static boolean isWindows = System.getProperty("os.name") .contains("Windows"); private TapProducer tapProducer = null; @Before public void setUp() { tapProducer = new TapProducer(); } /** * Tests planned tests in TAP. */ @Test public void testPlannedTests() { final TestSet testSet = new TestSet(); final Plan tapPlan = new Plan(2); testSet.setPlan(tapPlan); final TestResult result1 = new TestResult(StatusValues.OK, 1); testSet.addTestResult(result1); final TestResult result2 = new TestResult(StatusValues.OK, 2); testSet.addTestResult(result2); assertEquals(testSet.getTestResults().size(), 2); assertEquals(tapPlan.getLastTestNumber(), Integer.valueOf(2)); File tempFile = null; try { tempFile = File.createTempFile("tap4j", ".tap"); } catch (IOException ioe) { fail("Failed to create temp file: " + ioe.getMessage()); } try { tapProducer.dump(testSet, tempFile); } catch (ProducerException tpe) { fail("Failed to dump Test Set to file [" + tempFile + "]: " + tpe.getMessage()); } Integer exitCode = 1; try { exitCode = this.executePerlCommand(new String[] { "--planned=2" }, tempFile); } catch (Throwable t) { fail("Failed to execute Perl command: " + t.getMessage()); } assertEquals(exitCode, SUCCESS_EXIT_CODE); this.deleteTempFile(tempFile); } /** * Tests passed tests in TAP. */ @Test public void testPassedTests() { TestSet testSet = new TestSet(); final Plan tapPlan = new Plan(2); testSet.setPlan(tapPlan); TestResult result1 = new TestResult(StatusValues.OK, 1); testSet.addTestResult(result1); TestResult result2 = new TestResult(StatusValues.OK, 2); testSet.addTestResult(result2); assertEquals(testSet.getTestResults().size(), 2); assertEquals(tapPlan.getLastTestNumber(), Integer.valueOf(2)); File tempFile = null; try { tempFile = File.createTempFile("tap4j", ".tap"); } catch (IOException ioe) { fail("Failed to create temp file: " + ioe.getMessage()); } try { tapProducer.dump(testSet, tempFile); } catch (ProducerException tpe) { fail("Failed to dump Test Set to file [" + tempFile + "]: " + tpe.getMessage()); } Integer exitCode = 1; try { exitCode = this.executePerlCommand(new String[] { "--passed", "2" }, tempFile); } catch (Throwable t) { fail("Failed to execute Perl command: " + t.getMessage()); } assertEquals(exitCode, SUCCESS_EXIT_CODE); this.deleteTempFile(tempFile); } /** * Tests failed tests in TAP. */ @Test public void testFailedTests() { TestSet testSet = new TestSet(); final Plan tapPlan = new Plan(2); testSet.setPlan(tapPlan); TestResult result1 = new TestResult(StatusValues.NOT_OK, 1); testSet.addTestResult(result1); TestResult result2 = new TestResult(StatusValues.OK, 2); testSet.addTestResult(result2); assertEquals(testSet.getTestResults().size(), 2); assertEquals(tapPlan.getLastTestNumber(), Integer.valueOf(2)); File tempFile = null; try { tempFile = File.createTempFile("tap4j", ".tap"); } catch (IOException ioe) { fail("Failed to create temp file: " + ioe.getMessage()); } try { tapProducer.dump(testSet, tempFile); } catch (ProducerException tpe) { fail("Failed to dump Test Set to file [" + tempFile + "]: " + tpe.getMessage()); } Integer exitCode = 1; try { exitCode = this.executePerlCommand(new String[] { "--failed", "1" }, tempFile); } catch (Throwable t) { fail("Failed to execute Perl command: " + t.getMessage()); } assertEquals(exitCode, SUCCESS_EXIT_CODE); this.deleteTempFile(tempFile); } /** * Tests TO-DO'ed tests in TAP. */ @Test public void testTodoedTests() { TestSet testSet = new TestSet(); final Plan tapPlan = new Plan(2); testSet.setPlan(tapPlan); TestResult result1 = new TestResult(StatusValues.NOT_OK, 1); result1 .setDirective(new Directive(DirectiveValues.TODO, "Sample test")); testSet.addTestResult(result1); TestResult result2 = new TestResult(StatusValues.OK, 2); testSet.addTestResult(result2); assertEquals(testSet.getTestResults().size(), 2); assertEquals(tapPlan.getLastTestNumber(), Integer.valueOf(2)); File tempFile = null; try { tempFile = File.createTempFile("tap4j", ".tap"); } catch (IOException ioe) { fail("Failed to create temp file: " + ioe.getMessage()); } try { tapProducer.dump(testSet, tempFile); } catch (ProducerException tpe) { fail("Failed to dump Test Set to file [" + tempFile + "]: " + tpe.getMessage()); } Integer exitCode = 1; try { exitCode = this.executePerlCommand(new String[] { "--todo", "1" }, tempFile); } catch (Throwable t) { fail("Failed to execute Perl command: " + t.getMessage()); } assertEquals(exitCode, SUCCESS_EXIT_CODE); this.deleteTempFile(tempFile); } /** * Tests skipped tests in TAP. */ @Test public void testSkippedTestes() { TestSet testSet = new TestSet(); final Plan tapPlan = new Plan(2); testSet.setPlan(tapPlan); TestResult result1 = new TestResult(StatusValues.NOT_OK, 1); result1 .setDirective(new Directive(DirectiveValues.SKIP, "Sample test")); testSet.addTestResult(result1); TestResult result2 = new TestResult(StatusValues.OK, 2); testSet.addTestResult(result2); assertEquals(testSet.getTestResults().size(), 2); assertEquals(tapPlan.getLastTestNumber(), Integer.valueOf(2)); File tempFile = null; try { tempFile = File.createTempFile("tap4j", ".tap"); } catch (IOException ioe) { fail("Failed to create temp file: " + ioe.getMessage()); } try { tapProducer.dump(testSet, tempFile); } catch (ProducerException tpe) { fail("Failed to dump Test Set to file [" + tempFile + "]: " + tpe.getMessage()); } Integer exitCode = 1; try { exitCode = this.executePerlCommand(new String[] { "--skipped", "1" }, tempFile); } catch (Throwable t) { fail("Failed to execute Perl command: " + t.getMessage()); } assertEquals(exitCode, SUCCESS_EXIT_CODE); this.deleteTempFile(tempFile); } /** * Tests planned, passed, failed, TO-DO'ed and skipped tests in TAP. */ @Test public void testPannedPassedFailedTodoedSkipped() { TestSet testSet = new TestSet(); final Plan tapPlan = new Plan(6); testSet.setPlan(tapPlan); TestResult result1 = new TestResult(StatusValues.NOT_OK, 1); result1 .setDirective(new Directive(DirectiveValues.TODO, "Sample test")); testSet.addTestResult(result1); TestResult result2 = new TestResult(StatusValues.OK, 2); testSet.addTestResult(result2); TestResult result3 = new TestResult(StatusValues.OK, 3); testSet.addTestResult(result3); TestResult result4 = new TestResult(StatusValues.NOT_OK, 4); result4.setDirective(new Directive(DirectiveValues.SKIP, "Skip")); testSet.addTestResult(result4); TestResult result5 = new TestResult(StatusValues.OK, 5); result5.setDirective(new Directive(DirectiveValues.TODO, "someday who knows")); testSet.addTestResult(result5); TestResult result6 = new TestResult(StatusValues.NOT_OK, 6); testSet.addTestResult(result6); assertEquals(testSet.getTestResults().size(), 6); assertEquals(tapPlan.getLastTestNumber(), Integer.valueOf(6)); File tempFile = null; try { tempFile = File.createTempFile("tap4j", ".tap"); } catch (IOException ioe) { fail("Failed to create temp file: " + ioe.getMessage()); } try { tapProducer.dump(testSet, tempFile); } catch (ProducerException tpe) { fail("Failed to dump Test Set to file [" + tempFile + "]: " + tpe.getMessage()); } Integer exitCode = 1; try { exitCode = this.executePerlCommand(new String[] { "--planned", "6", "--passed", "4", // TODO in not_ok => ok "--failed", "2", "--todo", "2", "--skipped", "1" }, tempFile); } catch (Throwable t) { fail("Failed to execute Perl command: " + t.getMessage()); } assertEquals(exitCode, SUCCESS_EXIT_CODE); this.deleteTempFile(tempFile); } private Integer executePerlCommand(String[] args, File tapFile) { final File metatap = this.getMetatap(); Integer errorLevel = Integer.valueOf(1); try { List<String> commands = new LinkedList<String>(); if (TestPerlIntegration.isWindows) { commands.add("cmd"); commands.add("/c"); } else { commands.add("/bin/bash"); commands.add("-c"); } StringBuilder perlcommand = new StringBuilder(); perlcommand.append("perl "); perlcommand.append(metatap.getCanonicalPath().toString()); for (int i = 0; args != null && i < args.length; ++i) { perlcommand.append(" " + args[i]); } perlcommand.append(" < "); perlcommand.append(tapFile.getCanonicalPath().toString()); if (TestPerlIntegration.isWindows) { perlcommand.append(" && exit %%ERRORLEVEL%%"); } commands.add(perlcommand.toString()); Process p = Runtime.getRuntime().exec(commands .toArray(new String[0])); errorLevel = p.waitFor(); } catch (Throwable e) { throw new RuntimeException(e); } return errorLevel; } /** * Retrieves Perl metatap script. * * @return Perl metatap script. * @throws RuntimeException */ private File getMetatap() { URL url = ClassLoader.getSystemClassLoader().getResource("."); File classLoaderRoot = new File(url.getFile()); File metatap = new File(classLoaderRoot, "/../../src/test/perl/metatap.pl"); if (!metatap.exists()) { throw new RuntimeException("Missing metatap Perl file: " + metatap.toString()); } return metatap; } /** * Tries to delete a temporary file. * * @param tempFile temporary file. */ private void deleteTempFile(File tempFile) { if (tempFile != null && tempFile.exists()) { if (!tempFile.delete()) { tempFile.deleteOnExit(); } } } }