You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tika.apache.org by ta...@apache.org on 2015/03/06 15:41:08 UTC

svn commit: r1664635 - in /tika/trunk: ./ tika-core/src/test/java/org/apache/tika/parser/ tika-core/src/test/java/org/apache/tika/parser/mock/ tika-parsers/ tika-parsers/src/test/java/org/apache/tika/parser/evil/ tika-parsers/src/test/java/org/apache/t...

Author: tallison
Date: Fri Mar  6 14:41:07 2015
New Revision: 1664635

URL: http://svn.apache.org/r1664635
Log:
TIKA-1553 change EvilParser to MockParser and move to core

Added:
    tika/trunk/tika-core/src/test/java/org/apache/tika/parser/mock/
    tika/trunk/tika-core/src/test/java/org/apache/tika/parser/mock/MockParser.java
    tika/trunk/tika-parsers/src/test/java/org/apache/tika/parser/mock/
    tika/trunk/tika-parsers/src/test/java/org/apache/tika/parser/mock/MockParserTest.java
    tika/trunk/tika-parsers/src/test/resources/test-documents/mock/
    tika/trunk/tika-parsers/src/test/resources/test-documents/mock/example.xml
    tika/trunk/tika-parsers/src/test/resources/test-documents/mock/fake_oom.xml
    tika/trunk/tika-parsers/src/test/resources/test-documents/mock/heavy_hang.xml
    tika/trunk/tika-parsers/src/test/resources/test-documents/mock/nothing_bad.xml
    tika/trunk/tika-parsers/src/test/resources/test-documents/mock/null_pointer.xml
    tika/trunk/tika-parsers/src/test/resources/test-documents/mock/null_pointer_no_msg.xml
    tika/trunk/tika-parsers/src/test/resources/test-documents/mock/real_oom.xml
    tika/trunk/tika-parsers/src/test/resources/test-documents/mock/sleep.xml
    tika/trunk/tika-parsers/src/test/resources/test-documents/mock/sleep_interruptible.xml
    tika/trunk/tika-parsers/src/test/resources/test-documents/mock/sleep_not_interruptible.xml
    tika/trunk/tika-server/src/test/resources/mock/
    tika/trunk/tika-server/src/test/resources/mock/null_pointer.xml
Removed:
    tika/trunk/tika-parsers/src/test/java/org/apache/tika/parser/evil/
    tika/trunk/tika-parsers/src/test/resources/test-documents/evil/
    tika/trunk/tika-server/src/test/resources/evil/
Modified:
    tika/trunk/CHANGES.txt
    tika/trunk/tika-core/src/test/java/org/apache/tika/parser/DummyParser.java
    tika/trunk/tika-parsers/pom.xml
    tika/trunk/tika-parsers/src/test/resources/META-INF/services/org.apache.tika.parser.Parser
    tika/trunk/tika-parsers/src/test/resources/org/apache/tika/mime/custom-mimetypes.xml
    tika/trunk/tika-server/pom.xml
    tika/trunk/tika-server/src/test/java/org/apache/tika/server/StackTraceOffTest.java
    tika/trunk/tika-server/src/test/java/org/apache/tika/server/StackTraceTest.java

Modified: tika/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/tika/trunk/CHANGES.txt?rev=1664635&r1=1664634&r2=1664635&view=diff
==============================================================================
--- tika/trunk/CHANGES.txt (original)
+++ tika/trunk/CHANGES.txt Fri Mar  6 14:41:07 2015
@@ -23,7 +23,7 @@ Release 1.8 - Current Development
   * Tika's JAX-RS server can now return stacktraces for
     parse exceptions. (TIKA-1323)
 
-  * Added EvilParser for testing handling of exceptions, errors
+  * Added MockParser for testing handling of exceptions, errors
     and hangs in code that uses parsers. (TIKA-1533)
 
   * The ForkParser service removed from Activator. Rollback of (TIKA-1354).

Modified: tika/trunk/tika-core/src/test/java/org/apache/tika/parser/DummyParser.java
URL: http://svn.apache.org/viewvc/tika/trunk/tika-core/src/test/java/org/apache/tika/parser/DummyParser.java?rev=1664635&r1=1664634&r2=1664635&view=diff
==============================================================================
--- tika/trunk/tika-core/src/test/java/org/apache/tika/parser/DummyParser.java (original)
+++ tika/trunk/tika-core/src/test/java/org/apache/tika/parser/DummyParser.java Fri Mar  6 14:41:07 2015
@@ -31,6 +31,8 @@ import org.xml.sax.SAXException;
 
 /**
  * A Dummy Parser for use with unit tests.
+ * <p>
+ * See also {@link org.apache.tika.parser.mock.MockParser}.
  */
 public class DummyParser extends AbstractParser {
    private Set<MediaType> types;

Added: tika/trunk/tika-core/src/test/java/org/apache/tika/parser/mock/MockParser.java
URL: http://svn.apache.org/viewvc/tika/trunk/tika-core/src/test/java/org/apache/tika/parser/mock/MockParser.java?rev=1664635&view=auto
==============================================================================
--- tika/trunk/tika-core/src/test/java/org/apache/tika/parser/mock/MockParser.java (added)
+++ tika/trunk/tika-core/src/test/java/org/apache/tika/parser/mock/MockParser.java Fri Mar  6 14:41:07 2015
@@ -0,0 +1,289 @@
+package org.apache.tika.parser.mock;
+
+/*
+ * 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.
+ */
+
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.tika.exception.TikaException;
+import org.apache.tika.metadata.Metadata;
+import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.AbstractParser;
+import org.apache.tika.parser.ParseContext;
+import org.apache.tika.sax.XHTMLContentHandler;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * This class enables mocking of parser behavior for use in testing
+ * wrappers and drivers of parsers.
+ * <p>
+ * See resources/test-documents/mock/example.xml in tika-parsers/test for the documentation
+ * of all the options for this MockParser.
+ * <p>
+ * Tests for this class are in tika-parsers.
+ * <p>
+ * See also {@link org.apache.tika.parser.DummyParser} for another option.
+ */
+
+public class MockParser extends AbstractParser {
+
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    public Set<MediaType> getSupportedTypes(ParseContext context) {
+        Set<MediaType> types = new HashSet<MediaType>();
+        MediaType type = MediaType.application("mock+xml");
+        types.add(type);
+        return types;
+    }
+
+    @Override
+    public void parse(InputStream stream, ContentHandler handler,
+                      Metadata metadata, ParseContext context) throws IOException,
+            SAXException, TikaException {
+        Document doc = null;
+        DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
+        DocumentBuilder docBuilder = null;
+        try {
+            docBuilder = fact.newDocumentBuilder();
+            doc = docBuilder.parse(stream);
+        } catch (ParserConfigurationException e) {
+            throw new IOException(e);
+        } catch (SAXException e) {
+            throw new IOException(e);
+        }
+        Node root = doc.getDocumentElement();
+        NodeList actions = root.getChildNodes();
+        XHTMLContentHandler xhtml = new XHTMLContentHandler(handler, metadata);
+        xhtml.startDocument();
+        for (int i = 0; i < actions.getLength(); i++) {
+            executeAction(actions.item(i), metadata, xhtml);
+        }
+        xhtml.endDocument();
+    }
+
+    private void executeAction(Node action, Metadata metadata, XHTMLContentHandler xhtml) throws SAXException,
+            IOException, TikaException {
+
+        if (action.getNodeType() != 1) {
+            return;
+        }
+
+        String name = action.getNodeName();
+        if ("metadata".equals(name)) {
+            metadata(action, metadata);
+        } else if("write".equals(name)) {
+            write(action, xhtml);
+        } else if ("throw".equals(name)) {
+            throwIt(action);
+        } else if ("hang".equals(name)) {
+            hang(action);
+        } else if ("oom".equals(name)) {
+            kabOOM();
+        } else {
+            throw new RuntimeException("Didn't recognize mock action: "+name);
+        }
+    }
+
+    private void hang(Node action) {
+        boolean interruptible = true;
+        boolean heavy = false;
+        long millis = -1;
+        long pulseMillis = -1;
+        NamedNodeMap attrs = action.getAttributes();
+        Node iNode = attrs.getNamedItem("interruptible");
+        if (iNode != null) {
+            interruptible = ("true".equals(iNode.getNodeValue()));
+        }
+        Node hNode = attrs.getNamedItem("heavy");
+        if (hNode != null) {
+            heavy = ("true".equals(hNode.getNodeValue()));
+        }
+
+        Node mNode = attrs.getNamedItem("millis");
+        if (mNode == null) {
+            throw new RuntimeException("Must specify \"millis\" attribute for hang.");
+        }
+        String millisString = mNode.getNodeValue();
+        try {
+            millis = Long.parseLong(millisString);
+        } catch (NumberFormatException e) {
+            throw new RuntimeException("Value for \"millis\" attribute must be a long.");
+        }
+
+        if (heavy) {
+            Node pNode = attrs.getNamedItem("pulse_millis");
+            if (pNode == null) {
+                throw new RuntimeException("Must specify attribute \"pulse_millis\" if the hang is \"heavy\"");
+            }
+            String pulseMillisString = mNode.getNodeValue();
+            try {
+                pulseMillis = Long.parseLong(pulseMillisString);
+            } catch (NumberFormatException e) {
+                throw new RuntimeException("Value for \"millis\" attribute must be a long.");
+            }
+        }
+        if (heavy) {
+            hangHeavy(millis, pulseMillis, interruptible);
+        } else {
+            sleep(millis, interruptible);
+        }
+    }
+
+    private void throwIt(Node action) throws IOException,
+            SAXException, TikaException {
+        NamedNodeMap attrs = action.getAttributes();
+        String className = attrs.getNamedItem("class").getNodeValue();
+        String msg = action.getTextContent();
+        throwIt(className, msg);
+    }
+
+    private void metadata(Node action, Metadata metadata) {
+        NamedNodeMap attrs = action.getAttributes();
+        //throws npe unless there is a name
+        String name = attrs.getNamedItem("name").getNodeValue();
+        String value = action.getTextContent();
+        Node actionType = attrs.getNamedItem("action");
+        if (actionType == null) {
+            metadata.add(name, value);
+        } else {
+            if ("set".equals(actionType.getNodeValue())) {
+                metadata.set(name, value);
+            } else {
+                metadata.add(name, value);
+            }
+        }
+    }
+
+    private void write(Node action, XHTMLContentHandler xhtml) throws SAXException {
+        NamedNodeMap attrs = action.getAttributes();
+        Node eNode = attrs.getNamedItem("element");
+        String elementType = "p";
+        if (eNode != null) {
+            elementType = eNode.getTextContent();
+        }
+        String text = action.getTextContent();
+        xhtml.startElement(elementType);
+        xhtml.characters(text);
+        xhtml.endElement(elementType);
+    }
+
+
+    private void throwIt(String className, String msg) throws IOException,
+            SAXException, TikaException {
+        Throwable t = null;
+        if (msg == null || msg.equals("")) {
+            try {
+                t = (Throwable) Class.forName(className).newInstance();
+            } catch (Exception e) {
+                throw new RuntimeException("couldn't create throwable class:"+className, e);
+            }
+        } else {
+            try {
+                Class<?> clazz = Class.forName(className);
+                Constructor<?> con = clazz.getConstructor(String.class);
+                t = (Throwable) con.newInstance(msg);
+            } catch (Exception e) {
+                throw new RuntimeException("couldn't create throwable class:" + className, e);
+            }
+        }
+        if (t instanceof SAXException) {
+            throw (SAXException)t;
+        } else if (t instanceof IOException) {
+            throw (IOException) t;
+        } else if (t instanceof TikaException) {
+            throw (TikaException) t;
+        } else if (t instanceof Error) {
+            throw (Error) t;
+        } else if (t instanceof RuntimeException) {
+            throw (RuntimeException) t;
+        } else {
+            //wrap the throwable in a RuntimeException
+            throw new RuntimeException(t);
+        }
+    }
+
+    private void kabOOM() {
+        List<int[]> ints = new ArrayList<int[]>();
+
+        while (true) {
+            int[] intArr = new int[32000];
+            ints.add(intArr);
+        }
+    }
+
+    private void hangHeavy(long maxMillis, long pulseCheckMillis, boolean interruptible) {
+        //do some heavy computation and occasionally check for
+        //whether time has exceeded maxMillis (see TIKA-1132 for inspiration)
+        //or whether the thread was interrupted
+        long start = new Date().getTime();
+        int lastChecked = 0;
+        while (true) {
+            for (int i = 1; i < Integer.MAX_VALUE; i++) {
+                for (int j = 1; j < Integer.MAX_VALUE; j++) {
+                    double div = (double) i / (double) j;
+                    lastChecked++;
+                    if (lastChecked > pulseCheckMillis) {
+                        lastChecked = 0;
+                        if (interruptible && Thread.currentThread().isInterrupted()) {
+                            return;
+                        }
+                        long elapsed = new Date().getTime()-start;
+                        if (elapsed > maxMillis) {
+                            return;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void sleep(long maxMillis, boolean isInterruptible) {
+        long start = new Date().getTime();
+        long millisRemaining = maxMillis;
+        while (true) {
+            try {
+                Thread.sleep(millisRemaining);
+            } catch (InterruptedException e) {
+                if (isInterruptible) {
+                    return;
+                }
+            }
+            long elapsed = new Date().getTime()-start;
+            millisRemaining = maxMillis - elapsed;
+            if (millisRemaining <= 0) {
+                break;
+            }
+        }
+    }
+}
\ No newline at end of file

Modified: tika/trunk/tika-parsers/pom.xml
URL: http://svn.apache.org/viewvc/tika/trunk/tika-parsers/pom.xml?rev=1664635&r1=1664634&r2=1664635&view=diff
==============================================================================
--- tika/trunk/tika-parsers/pom.xml (original)
+++ tika/trunk/tika-parsers/pom.xml Fri Mar  6 14:41:07 2015
@@ -63,6 +63,14 @@
       <version>${project.version}</version>
     </dependency>
 
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>tika-core</artifactId>
+      <version>${project.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+
     <!-- Externally Maintained Parsers -->
     <dependency>
       <groupId>org.gagravarr</groupId>

Added: tika/trunk/tika-parsers/src/test/java/org/apache/tika/parser/mock/MockParserTest.java
URL: http://svn.apache.org/viewvc/tika/trunk/tika-parsers/src/test/java/org/apache/tika/parser/mock/MockParserTest.java?rev=1664635&view=auto
==============================================================================
--- tika/trunk/tika-parsers/src/test/java/org/apache/tika/parser/mock/MockParserTest.java (added)
+++ tika/trunk/tika-parsers/src/test/java/org/apache/tika/parser/mock/MockParserTest.java Fri Mar  6 14:41:07 2015
@@ -0,0 +1,225 @@
+package org.apache.tika.parser.mock;
+
+/*
+ * 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.
+ */
+
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+
+import org.apache.tika.TikaTest;
+import org.apache.tika.exception.TikaException;
+import org.apache.tika.io.IOUtils;
+import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.AutoDetectParser;
+import org.apache.tika.parser.Parser;
+import org.junit.Test;
+
+public class MockParserTest extends TikaTest {
+    private final static String M = "/test-documents/mock/";
+    private final static Parser PARSER = new AutoDetectParser();
+
+    @Override
+    public XMLResult getXML(String path, Metadata m) throws Exception {
+        //note that this is specific to MockParserTest with addition of M to the path!
+        InputStream is = getResourceAsStream(M+path);
+        try {
+            return super.getXML(is, PARSER, m);
+        } finally {
+            IOUtils.closeQuietly(is);
+        }
+    }
+
+    @Test
+    public void testExample() throws Exception {
+        Metadata m = new Metadata();
+        assertThrowable("example.xml", m, IOException.class, "not another IOException");
+        assertMockParser(m);
+    }
+
+    @Test
+    public void testNothingBad() throws Exception {
+        Metadata m = new Metadata();
+        String content = getXML("nothing_bad.xml", m).xml;
+        assertEquals("Geoffrey Chaucer", m.get("author"));
+        assertContains("<p>And bathed every veyne in swich licour,</p>", content);
+        assertMockParser(m);
+    }
+
+    @Test
+    public void testNullPointer() throws Exception {
+        Metadata m = new Metadata();
+        assertThrowable("null_pointer.xml", m, NullPointerException.class, "another null pointer exception");
+        assertMockParser(m);
+    }
+
+    @Test
+    public void testNullPointerNoMsg() throws Exception {
+        Metadata m = new Metadata();
+        assertThrowable("null_pointer_no_msg.xml", m, NullPointerException.class, null);
+        assertMockParser(m);
+    }
+
+
+    @Test
+    public void testSleep() throws Exception {
+        long start = new Date().getTime();
+        Metadata m = new Metadata();
+        String content = getXML("sleep.xml", m).xml;
+        assertMockParser(m);
+        long elapsed = new Date().getTime()-start;
+        //should sleep for at least 3000
+        boolean enoughTimeHasElapsed = elapsed > 2000;
+        assertTrue("not enough time has not elapsed: "+elapsed, enoughTimeHasElapsed);
+        assertMockParser(m);
+    }
+
+    @Test
+    public void testHeavyHang() throws Exception {
+        long start = new Date().getTime();
+        Metadata m = new Metadata();
+
+        String content = getXML("heavy_hang.xml", m).xml;
+        assertMockParser(m);
+        long elapsed = new Date().getTime()-start;
+        //should sleep for at least 3000
+        boolean enoughTimeHasElapsed = elapsed > 2000;
+        assertTrue("not enough time has elapsed: "+elapsed, enoughTimeHasElapsed);
+        assertMockParser(m);
+    }
+
+    @Test
+    public void testFakeOOM() throws Exception {
+        Metadata m = new Metadata();
+        assertThrowable("fake_oom.xml", m, OutOfMemoryError.class, "not another oom");
+        assertMockParser(m);
+    }
+
+    @Test
+    public void testRealOOM() throws Exception {
+        //Note: we're not actually testing the diff between fake and real oom
+        //i.e. by creating child process and setting different -Xmx or
+        //memory profiling.
+        Metadata m = new Metadata();
+        assertThrowable("real_oom.xml", m, OutOfMemoryError.class, "Java heap space");
+        assertMockParser(m);
+    }
+
+    @Test
+    public void testInterruptibleSleep() {
+        //Without static initialization of the parser, it can take ~1 second after t.start()
+        //before the parser actually calls parse.  This is
+        //just the time it takes to instantiate and call AutoDetectParser, do the detection, etc.
+        //This is not thread creation overhead.
+        ParserRunnable r = new ParserRunnable("sleep_interruptible.xml");
+        Thread t = new Thread(r);
+        t.start();
+        long start = new Date().getTime();
+        try {
+            Thread.sleep(1000);
+        } catch (InterruptedException e) {
+            //swallow
+        }
+
+        t.interrupt();
+
+        try {
+            t.join(10000);
+        } catch (InterruptedException e) {
+            //swallow
+        }
+        long elapsed = new Date().getTime()-start;
+        boolean shortEnough = elapsed < 2000;//the xml file specifies 3000
+        assertTrue("elapsed (" + elapsed + " millis) was not short enough", shortEnough);
+    }
+
+    @Test
+    public void testNonInterruptibleSleep() {
+        ParserRunnable r = new ParserRunnable("sleep_not_interruptible.xml");
+        Thread t = new Thread(r);
+        t.start();
+        long start = new Date().getTime();
+        try {
+            //make sure that the thread has actually started
+            Thread.sleep(1000);
+        } catch (InterruptedException e) {
+            //swallow
+        }
+        t.interrupt();
+        try {
+            t.join(20000);
+        } catch (InterruptedException e) {
+            //swallow
+        }
+        long elapsed = new Date().getTime()-start;
+        boolean longEnough = elapsed > 3000;//the xml file specifies 3000, this sleeps 1000
+        assertTrue("elapsed ("+elapsed+" millis) was not long enough", longEnough);
+    }
+
+    private class ParserRunnable implements Runnable {
+        private final String path;
+        ParserRunnable(String path) {
+            this.path = path;
+        }
+        @Override
+        public void run() {
+            Metadata m = new Metadata();
+            try {
+                getXML(path, m);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            } finally {
+                assertMockParser(m);
+            }
+        }
+    }
+
+    private void assertThrowable(String path, Metadata m, Class<? extends Throwable> expected, String message) {
+
+        try {
+            getXML(path, m);
+        } catch (Throwable t) {
+            //if this is a throwable wrapped in a TikaException, use the cause
+            if (t instanceof TikaException && t.getCause() != null) {
+                t = t.getCause();
+            }
+            if (! (t.getClass().isAssignableFrom(expected))){
+                fail(t.getClass() +" is not assignable from "+expected);
+            }
+            if (message != null) {
+                assertEquals(message, t.getMessage());
+            }
+        }
+    }
+
+    private void assertMockParser(Metadata m) {
+        String[] parsers = m.getValues("X-Parsed-By");
+        //make sure that it was actually parsed by mock.
+        boolean parsedByMock = false;
+        for (String parser : parsers) {
+            if (parser.equals("org.apache.tika.parser.mock.MockParser")) {
+                parsedByMock = true;
+                break;
+            }
+        }
+        assertTrue("mock parser should have been called", parsedByMock);
+    }
+}

Modified: tika/trunk/tika-parsers/src/test/resources/META-INF/services/org.apache.tika.parser.Parser
URL: http://svn.apache.org/viewvc/tika/trunk/tika-parsers/src/test/resources/META-INF/services/org.apache.tika.parser.Parser?rev=1664635&r1=1664634&r2=1664635&view=diff
==============================================================================
--- tika/trunk/tika-parsers/src/test/resources/META-INF/services/org.apache.tika.parser.Parser (original)
+++ tika/trunk/tika-parsers/src/test/resources/META-INF/services/org.apache.tika.parser.Parser Fri Mar  6 14:41:07 2015
@@ -1 +1 @@
-org.apache.tika.parser.evil.EvilParser
\ No newline at end of file
+org.apache.tika.parser.mock.MockParser
\ No newline at end of file

Modified: tika/trunk/tika-parsers/src/test/resources/org/apache/tika/mime/custom-mimetypes.xml
URL: http://svn.apache.org/viewvc/tika/trunk/tika-parsers/src/test/resources/org/apache/tika/mime/custom-mimetypes.xml?rev=1664635&r1=1664634&r2=1664635&view=diff
==============================================================================
--- tika/trunk/tika-parsers/src/test/resources/org/apache/tika/mime/custom-mimetypes.xml (original)
+++ tika/trunk/tika-parsers/src/test/resources/org/apache/tika/mime/custom-mimetypes.xml Fri Mar  6 14:41:07 2015
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <mime-info>
-    <mime-type type="application/evil">
-        <glob pattern="*.evil"/>
-        <sub-class-of type="text/plain"/>
+    <mime-type type="application/mock+xml">
+        <root-XML localName="mock"/>
+        <sub-class-of type="application/xml"/>
     </mime-type>
 </mime-info>
\ No newline at end of file

Added: tika/trunk/tika-parsers/src/test/resources/test-documents/mock/example.xml
URL: http://svn.apache.org/viewvc/tika/trunk/tika-parsers/src/test/resources/test-documents/mock/example.xml?rev=1664635&view=auto
==============================================================================
--- tika/trunk/tika-parsers/src/test/resources/test-documents/mock/example.xml (added)
+++ tika/trunk/tika-parsers/src/test/resources/test-documents/mock/example.xml Fri Mar  6 14:41:07 2015
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  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.
+-->
+
+<mock>
+    <!-- this file offers all of the options as documentation
+    Parsing should stop at an IOException, of course
+    -->
+
+    <!-- action can be "add" or "set" -->
+    <metadata action="add" name="author">Nikolai Lobachevsky</metadata>
+    <!-- element is the name of the sax event to write, p=paragraph
+        if the element is not specified, the default is <p> -->
+    <write element="p">some content</write>
+    <!-- hang
+        millis: how many milliseconds to pause.  The actual hang time will probably
+            be a bit longer than the value specified.
+        heavy: whether or not the hang should do something computationally expensive.
+            If the value is false, this just does a Thread.sleep(millis).
+            This attribute is optional, with default of heavy=false.
+        pulse_millis: (required if "heavy" is true), how often to check to see
+            whether the thread was interrupted or that the total hang time exceeded the millis
+        interruptible: whether or not the parser will check to see if its thread
+            has been interrupted; this attribute is optional with default of true
+    -->
+    <hang millis="100" heavy="true" pulse_millis="10" interruptible="true" />
+    <!-- throw an exception or error; optionally include a message or not -->
+    <throw class="java.io.IOException">not another IOException</throw>
+    <!-- perform a genuine OutOfMemoryError -->
+    <oom/>
+</mock>
\ No newline at end of file

Added: tika/trunk/tika-parsers/src/test/resources/test-documents/mock/fake_oom.xml
URL: http://svn.apache.org/viewvc/tika/trunk/tika-parsers/src/test/resources/test-documents/mock/fake_oom.xml?rev=1664635&view=auto
==============================================================================
--- tika/trunk/tika-parsers/src/test/resources/test-documents/mock/fake_oom.xml (added)
+++ tika/trunk/tika-parsers/src/test/resources/test-documents/mock/fake_oom.xml Fri Mar  6 14:41:07 2015
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  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.
+-->
+
+<mock>
+    <metadata action="add" name="author">Nikolai Lobachevsky</metadata>
+    <throw class="java.lang.OutOfMemoryError">not another oom</throw>
+</mock>
\ No newline at end of file

Added: tika/trunk/tika-parsers/src/test/resources/test-documents/mock/heavy_hang.xml
URL: http://svn.apache.org/viewvc/tika/trunk/tika-parsers/src/test/resources/test-documents/mock/heavy_hang.xml?rev=1664635&view=auto
==============================================================================
--- tika/trunk/tika-parsers/src/test/resources/test-documents/mock/heavy_hang.xml (added)
+++ tika/trunk/tika-parsers/src/test/resources/test-documents/mock/heavy_hang.xml Fri Mar  6 14:41:07 2015
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  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.
+-->
+
+<mock>
+    <metadata action="add" name="author">Nikolai Lobachevsky</metadata>
+    <write element="p">some content</write>
+    <hang millis="3000" heavy="true" pulse_millis="100" />
+</mock>
\ No newline at end of file

Added: tika/trunk/tika-parsers/src/test/resources/test-documents/mock/nothing_bad.xml
URL: http://svn.apache.org/viewvc/tika/trunk/tika-parsers/src/test/resources/test-documents/mock/nothing_bad.xml?rev=1664635&view=auto
==============================================================================
--- tika/trunk/tika-parsers/src/test/resources/test-documents/mock/nothing_bad.xml (added)
+++ tika/trunk/tika-parsers/src/test/resources/test-documents/mock/nothing_bad.xml Fri Mar  6 14:41:07 2015
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  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.
+-->
+
+<mock>
+    <metadata action="add" name="author">Geoffrey Chaucer</metadata>
+    <write element="p">Whan that Aprille with his shoures soote</write>
+    <write>The droghte of Marche hath perced to the roote,</write>
+    <write>And bathed every veyne in swich licour,</write>
+</mock>
\ No newline at end of file

Added: tika/trunk/tika-parsers/src/test/resources/test-documents/mock/null_pointer.xml
URL: http://svn.apache.org/viewvc/tika/trunk/tika-parsers/src/test/resources/test-documents/mock/null_pointer.xml?rev=1664635&view=auto
==============================================================================
--- tika/trunk/tika-parsers/src/test/resources/test-documents/mock/null_pointer.xml (added)
+++ tika/trunk/tika-parsers/src/test/resources/test-documents/mock/null_pointer.xml Fri Mar  6 14:41:07 2015
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  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.
+-->
+
+<mock>
+    <metadata action="add" name="author">Nikolai Lobachevsky</metadata>
+    <write element="p">some content</write>
+    <throw class="java.lang.NullPointerException">another null pointer exception</throw>
+</mock>
\ No newline at end of file

Added: tika/trunk/tika-parsers/src/test/resources/test-documents/mock/null_pointer_no_msg.xml
URL: http://svn.apache.org/viewvc/tika/trunk/tika-parsers/src/test/resources/test-documents/mock/null_pointer_no_msg.xml?rev=1664635&view=auto
==============================================================================
--- tika/trunk/tika-parsers/src/test/resources/test-documents/mock/null_pointer_no_msg.xml (added)
+++ tika/trunk/tika-parsers/src/test/resources/test-documents/mock/null_pointer_no_msg.xml Fri Mar  6 14:41:07 2015
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  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.
+-->
+
+<mock>
+    <metadata action="add" name="author">Nikolai Lobachevsky</metadata>
+    <write element="p">some content</write>
+    <throw class="java.lang.NullPointerException"/>
+</mock>
\ No newline at end of file

Added: tika/trunk/tika-parsers/src/test/resources/test-documents/mock/real_oom.xml
URL: http://svn.apache.org/viewvc/tika/trunk/tika-parsers/src/test/resources/test-documents/mock/real_oom.xml?rev=1664635&view=auto
==============================================================================
--- tika/trunk/tika-parsers/src/test/resources/test-documents/mock/real_oom.xml (added)
+++ tika/trunk/tika-parsers/src/test/resources/test-documents/mock/real_oom.xml Fri Mar  6 14:41:07 2015
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  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.
+-->
+
+<mock>
+    <metadata action="add" name="author">Nikolai Lobachevsky</metadata>
+    <oom/>
+</mock>
\ No newline at end of file

Added: tika/trunk/tika-parsers/src/test/resources/test-documents/mock/sleep.xml
URL: http://svn.apache.org/viewvc/tika/trunk/tika-parsers/src/test/resources/test-documents/mock/sleep.xml?rev=1664635&view=auto
==============================================================================
--- tika/trunk/tika-parsers/src/test/resources/test-documents/mock/sleep.xml (added)
+++ tika/trunk/tika-parsers/src/test/resources/test-documents/mock/sleep.xml Fri Mar  6 14:41:07 2015
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  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.
+-->
+
+<mock>
+    <metadata action="add" name="author">Nikolai Lobachevsky</metadata>
+    <write element="p">some content</write>
+    <hang millis="3000" heavy="false"  />
+</mock>
\ No newline at end of file

Added: tika/trunk/tika-parsers/src/test/resources/test-documents/mock/sleep_interruptible.xml
URL: http://svn.apache.org/viewvc/tika/trunk/tika-parsers/src/test/resources/test-documents/mock/sleep_interruptible.xml?rev=1664635&view=auto
==============================================================================
--- tika/trunk/tika-parsers/src/test/resources/test-documents/mock/sleep_interruptible.xml (added)
+++ tika/trunk/tika-parsers/src/test/resources/test-documents/mock/sleep_interruptible.xml Fri Mar  6 14:41:07 2015
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  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.
+-->
+
+<mock>
+    <metadata action="add" name="author">Nikolai Lobachevsky</metadata>
+    <write element="p">some content</write>
+    <hang millis="3000" heavy="false" interruptible="true" />
+</mock>
\ No newline at end of file

Added: tika/trunk/tika-parsers/src/test/resources/test-documents/mock/sleep_not_interruptible.xml
URL: http://svn.apache.org/viewvc/tika/trunk/tika-parsers/src/test/resources/test-documents/mock/sleep_not_interruptible.xml?rev=1664635&view=auto
==============================================================================
--- tika/trunk/tika-parsers/src/test/resources/test-documents/mock/sleep_not_interruptible.xml (added)
+++ tika/trunk/tika-parsers/src/test/resources/test-documents/mock/sleep_not_interruptible.xml Fri Mar  6 14:41:07 2015
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  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.
+-->
+
+<mock>
+    <metadata action="add" name="author">Nikolai Lobachevsky</metadata>
+    <write element="p">some content</write>
+    <hang millis="3000" heavy="false" interruptible="false" />
+</mock>
\ No newline at end of file

Modified: tika/trunk/tika-server/pom.xml
URL: http://svn.apache.org/viewvc/tika/trunk/tika-server/pom.xml?rev=1664635&r1=1664634&r2=1664635&view=diff
==============================================================================
--- tika/trunk/tika-server/pom.xml (original)
+++ tika/trunk/tika-server/pom.xml Fri Mar  6 14:41:07 2015
@@ -99,6 +99,13 @@
     </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
+      <artifactId>tika-core</artifactId>
+      <version>${project.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
       <artifactId>tika-parsers</artifactId>
       <version>${project.version}</version>
       <type>test-jar</type>

Modified: tika/trunk/tika-server/src/test/java/org/apache/tika/server/StackTraceOffTest.java
URL: http://svn.apache.org/viewvc/tika/trunk/tika-server/src/test/java/org/apache/tika/server/StackTraceOffTest.java?rev=1664635&r1=1664634&r2=1664635&view=diff
==============================================================================
--- tika/trunk/tika-server/src/test/java/org/apache/tika/server/StackTraceOffTest.java (original)
+++ tika/trunk/tika-server/src/test/java/org/apache/tika/server/StackTraceOffTest.java Fri Mar  6 14:41:07 2015
@@ -40,7 +40,7 @@ import org.junit.Test;
  * when the stack trace param is set to false.
  */
 public class StackTraceOffTest extends CXFTestBase {
-    public static final String TEST_NULL = "evil/null_pointer.evil";
+    public static final String TEST_NULL = "mock/null_pointer.xml";
     public static final String TEST_PASSWORD_PROTECTED = "password.xls";
 
     private static final String[] PATHS = new String[]{
@@ -96,8 +96,6 @@ public class StackTraceOffTest extends C
             Response response = WebClient
                     .create(endPoint + path)
                     .accept("*/*")
-                    .header("Content-Disposition",
-                            "attachment; filename=null_pointer.evil")
                     .put(ClassLoader.getSystemResourceAsStream(TEST_NULL));
             assertNotNull("null response: " + path, response);
             assertEquals("unprocessable: " + path, UNPROCESSEABLE, response.getStatus());

Modified: tika/trunk/tika-server/src/test/java/org/apache/tika/server/StackTraceTest.java
URL: http://svn.apache.org/viewvc/tika/trunk/tika-server/src/test/java/org/apache/tika/server/StackTraceTest.java?rev=1664635&r1=1664634&r2=1664635&view=diff
==============================================================================
--- tika/trunk/tika-server/src/test/java/org/apache/tika/server/StackTraceTest.java (original)
+++ tika/trunk/tika-server/src/test/java/org/apache/tika/server/StackTraceTest.java Fri Mar  6 14:41:07 2015
@@ -34,7 +34,7 @@ import org.junit.Assert;
 import org.junit.Test;
 
 public class StackTraceTest extends CXFTestBase {
-    public static final String TEST_NULL = "evil/null_pointer.evil";
+    public static final String TEST_NULL = "mock/null_pointer.xml";
     public static final String TEST_PASSWORD_PROTECTED = "password.xls";
 
     private static final String[] PATHS = new String[]{
@@ -91,8 +91,6 @@ public class StackTraceTest extends CXFT
             Response response = WebClient
                     .create(endPoint + path)
                     .accept("*/*")
-                    .header("Content-Disposition",
-                            "attachment; filename=null_pointer.evil")
                     .put(ClassLoader.getSystemResourceAsStream(TEST_NULL));
             assertNotNull("null response: " + path, response);
             assertEquals("unprocessable: " + path, UNPROCESSEABLE, response.getStatus());

Added: tika/trunk/tika-server/src/test/resources/mock/null_pointer.xml
URL: http://svn.apache.org/viewvc/tika/trunk/tika-server/src/test/resources/mock/null_pointer.xml?rev=1664635&view=auto
==============================================================================
--- tika/trunk/tika-server/src/test/resources/mock/null_pointer.xml (added)
+++ tika/trunk/tika-server/src/test/resources/mock/null_pointer.xml Fri Mar  6 14:41:07 2015
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  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.
+-->
+
+<mock>
+    <metadata action="add" name="author">Nikolai Lobachevsky</metadata>
+    <write element="p">some content</write>
+    <throw class="java.lang.NullPointerException">null pointer message</throw>
+</mock>