Author: bimargulies
Date: Sun Apr  5 11:17:11 2009
New Revision: 762071

URL: http://svn.apache.org/viewvc?rev=762071&view=rev
Log:
Complete the confused process of moving this test into the 'right' package.

Added:
    
webservices/commons/trunk/modules/XmlSchema/src/test/java/org/apache/ws/commons/schema/SchemaBuilderCacheTest.java
   (with props)

Added: 
webservices/commons/trunk/modules/XmlSchema/src/test/java/org/apache/ws/commons/schema/SchemaBuilderCacheTest.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/XmlSchema/src/test/java/org/apache/ws/commons/schema/SchemaBuilderCacheTest.java?rev=762071&view=auto
==============================================================================
--- 
webservices/commons/trunk/modules/XmlSchema/src/test/java/org/apache/ws/commons/schema/SchemaBuilderCacheTest.java
 (added)
+++ 
webservices/commons/trunk/modules/XmlSchema/src/test/java/org/apache/ws/commons/schema/SchemaBuilderCacheTest.java
 Sun Apr  5 11:17:11 2009
@@ -0,0 +1,422 @@
+/**
+ * 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.ws.commons.schema;
+
+import java.lang.ref.SoftReference;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import tests.Resources;
+
+/**
+ * Test the resolved Schema cache.
+ */
+public class SchemaBuilderCacheTest extends Assert {
+
+    // Amount of time the testcase should wait on the test threads before 
timing
+    // out
+    private static final int THREAD_TIMEOUT = 90000;
+
+    /**
+     * return resolved schema map.
+     */
+    static ThreadLocal<Map<String, SoftReference<XmlSchema>>> 
getResolvedSchemasHashtable() {
+        return SchemaBuilder.resolvedSchemas;
+    }
+
+    /**
+     * Return the HashMap for the current thread or null if there is not one.
+     * 
+     * @return
+     */
+    static Map<String, SoftReference<XmlSchema>> 
getThreadResolvedSchemaHashtable() {
+        return getResolvedSchemasHashtable().get();
+    }
+
+    // 
==============================================================================================
+    // Utility Methods
+    // 
==============================================================================================
+
+    /**
+     * Set the resolvedSchemas collection to null. This should be done in a
+     * finally block of any tests that cause an SchemaBuilder.initCache to be
+     * done to cleanup for the next test.
+     */
+    static void resetResolvedSchemasHashtable() {
+        SchemaBuilder.resolvedSchemas = new ThreadLocal<Map<String, 
SoftReference<XmlSchema>>>();
+    }
+
+    static Document setupDocument() {
+        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
+                .newInstance();
+        documentBuilderFactory.setNamespaceAware(true);
+        Document doc;
+        try {
+            doc = documentBuilderFactory.newDocumentBuilder().parse(
+                    Resources.asURI("importBase.xsd"));
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return doc;
+    }
+
+    static XmlSchemaCollection setupXmlSchemaCollection() {
+        XmlSchemaCollection schemaCol = new XmlSchemaCollection();
+        schemaCol.setBaseUri(Resources.TEST_RESOURCES);
+        return schemaCol;
+    }
+
+    /**
+     * Test that threads can not affect the cache for other threads.
+     */
+    @Test
+    public void testMultithreadCache() {
+        try {
+            MultithreadUpdateLockMonitor testMonitor = new 
MultithreadUpdateLockMonitor();
+            startupTestThreads(testMonitor);
+
+            if (testMonitor.t1Exception != null) {
+                fail("Thread T1 encountred an error: "
+                        + testMonitor.t1Exception.toString());
+            }
+            if (testMonitor.t2Exception != null) {
+                fail("Thread T2 encountred an error: "
+                        + testMonitor.t2Exception.toString());
+            }
+            if (testMonitor.t3Exception != null) {
+                fail("Thread T3 encountred an error: "
+                        + testMonitor.t3Exception.toString());
+            }
+        } finally {
+            resetResolvedSchemasHashtable();
+        }
+    }
+
+    /**
+     * Test if the cache is initialized it will be populated when a schema is
+     * read and it will be cleared when the clearCache method is called.
+     * 
+     * @throws Exception
+     */
+    @Test
+    public void testResolveCacheInitialized() throws Exception {
+        try {
+            SchemaBuilder.initCache();
+            Document doc = setupDocument();
+            XmlSchemaCollection schemaCol = setupXmlSchemaCollection();
+            XmlSchema schema = schemaCol.read(doc, null);
+            assertNotNull(schema);
+
+            // If the cache is in use, it should not be null and there should
+            // be an entry for this thread ID
+            assertNotNull(getResolvedSchemasHashtable());
+            Map<String, SoftReference<XmlSchema>> threadHT = 
getThreadResolvedSchemaHashtable();
+            assertNotNull(threadHT);
+            assertFalse(threadHT.isEmpty());
+            assertEquals(1, threadHT.size());
+
+            // After clearing the cache, there should be no entry for this
+            // thread ID, and
+            // the hashtable should not be null
+            SchemaBuilder.clearCache();
+            assertNotNull(getResolvedSchemasHashtable());
+            assertNull(getThreadResolvedSchemaHashtable());
+            System.out.println("Line 13");
+        } finally {
+            resetResolvedSchemasHashtable();
+        }
+
+        // If the cache is enabled, then it should be non-null
+    }
+
+    /**
+     * Test that if the cache is not initialized, then it should not be used
+     * when a schema is read.
+     * 
+     * @throws Exception
+     */
+    @Test
+    public void testResolveCacheUninitialized() throws Exception {
+        Document doc = setupDocument();
+        XmlSchemaCollection schemaCol = setupXmlSchemaCollection();
+        XmlSchema schema = schemaCol.read(doc, null);
+        assertNotNull(schema);
+
+        // If the cache is not in use, then it should be null
+        // The thread-local cannot be null
+        assertNull(getThreadResolvedSchemaHashtable());
+    }
+
+    /**
+     * Configure and start the test threads for the multi-threaded testing. The
+     * threads will perform various tests between themselves such as clearing
+     * cache in one thread and making sure the cache used by a different thread
+     * is not affected. A monitor is used to control the synchonization between
+     * the threads and for communicating faliures back to the test method.
+     * 
+     * See thed Runnable classes for details on the tests performed.
+     * 
+     * @param testMonitor
+     *            Used to synchronize the tests between the threads
+     */
+    private void startupTestThreads(MultithreadUpdateLockMonitor testMonitor) {
+        TestingRunnable1 testRunnable1 = new TestingRunnable1();
+        testRunnable1.testMonitor = testMonitor;
+
+        TestingRunnable2 testRunnable2 = new TestingRunnable2();
+        testRunnable2.testMonitor = testMonitor;
+
+        TestingRunnable3 testRunnable3 = new TestingRunnable3();
+        testRunnable3.testMonitor = testMonitor;
+
+        Thread thread1 = new Thread(testRunnable1);
+        Thread thread2 = new Thread(testRunnable2);
+        Thread thread3 = new Thread(testRunnable3);
+
+        thread1.start();
+        thread2.start();
+        thread3.start();
+
+        // Join the threads to wait for their completion, specifying a timeout
+        // to prevent
+        // a testcase hang if something goes wrong with the threads.
+        try {
+            thread1.join(THREAD_TIMEOUT);
+            thread2.join(THREAD_TIMEOUT);
+            thread3.join(THREAD_TIMEOUT);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+            fail("Unable to join to testing threads");
+        }
+    }
+}
+
+/**
+ * Monitor used to control synchronization between the testing threads and
+ * communicate failures back to the test method.
+ */
+class MultithreadUpdateLockMonitor {
+    Exception t1Exception;
+    boolean t1SetupComplete;
+    Exception t2Exception;
+    boolean t2SetupComplete;
+    Exception t3Exception;
+}
+
+// 
=================================================================================================
+// Test execution threads
+// 
=================================================================================================
+/**
+ * Thread 1 will do the following - Initialize the cache and verify it was used
+ * during a read - Unblock Thread 2 - Wait until Thread 2 unblocks it - Verify
+ * that the clearCache done by Thread 2 did not affect this Thread's cache.
+ */
+...@ignore
+class TestingRunnable1 implements Runnable {
+
+    MultithreadUpdateLockMonitor testMonitor;
+
+    public void run() {
+        SchemaBuilder.initCache();
+        Document doc = SchemaBuilderCacheTest.setupDocument();
+        XmlSchemaCollection schemaCol = SchemaBuilderCacheTest
+                .setupXmlSchemaCollection();
+        XmlSchema schema = schemaCol.read(doc, null);
+        if (schema == null) {
+            testMonitor.t1Exception = new Exception("Schema was null");
+        }
+
+        // If the cache is in use, it should not be null and there should be an
+        // entry for this
+        // Thread
+        if (SchemaBuilderCacheTest.getResolvedSchemasHashtable() == null) {
+            testMonitor.t1Exception = new Exception("resolvedSchemas was 
null");
+        }
+        Map<String, SoftReference<XmlSchema>> threadHT = SchemaBuilderCacheTest
+                .getThreadResolvedSchemaHashtable();
+        if (threadHT == null) {
+            testMonitor.t1Exception = new Exception(
+                    "Thread resolvedSchemas was null");
+        }
+
+        if (threadHT.isEmpty()) {
+            testMonitor.t1Exception = new Exception(
+                    "Thread resolvedSchemas was empty");
+        }
+
+        synchronized (testMonitor) {
+            testMonitor.t1SetupComplete = true;
+            testMonitor.notifyAll();
+            while (!testMonitor.t2SetupComplete) {
+                try {
+                    testMonitor.wait();
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                    testMonitor.t1Exception = new RuntimeException(e);
+                    throw (RuntimeException) testMonitor.t1Exception;
+                }
+            }
+        }
+
+        // After the other thread does a reset, the cache for this thread 
should
+        // NOT be null
+        if (SchemaBuilderCacheTest.getResolvedSchemasHashtable() == null) {
+            testMonitor.t1Exception = new Exception(
+                    "resolvedSchemas was null after reset");
+        }
+        threadHT = SchemaBuilderCacheTest.getThreadResolvedSchemaHashtable();
+        if (threadHT == null) {
+            testMonitor.t1Exception = new Exception(
+                    "Thread resolvedSchemas was null after clear");
+        }
+
+        if (threadHT.isEmpty()) {
+            testMonitor.t1Exception = new Exception(
+                    "Thread resolvedSchemas was empty after clear");
+        }
+
+        // Issue our a clear on this TID, and now there should be no entires 
for
+        // it
+        SchemaBuilder.clearCache();
+        if (SchemaBuilderCacheTest.getResolvedSchemasHashtable() == null) {
+            testMonitor.t1Exception = new Exception(
+                    "resolvedSchemas was null after clear on TID");
+        }
+
+        threadHT = SchemaBuilderCacheTest.getThreadResolvedSchemaHashtable();
+        if (threadHT != null) {
+            testMonitor.t1Exception = new Exception(
+                    "Thread resolvedSchemas was not null after clear");
+        }
+    }
+}
+
+/**
+ * Thread 2 will: - Block until released by Thread 1 - Initialize the cache 
then
+ * make sure it was used for a resolve on this thread - clear the cache and 
make
+ * sure the entries for this Thread a removed - Unblock Thread 1 to make sure
+ * the clear did not affect it
+ */
+...@ignore
+class TestingRunnable2 implements Runnable {
+
+    MultithreadUpdateLockMonitor testMonitor;
+
+    public void run() {
+        synchronized (testMonitor) {
+            while (!testMonitor.t1SetupComplete) {
+                try {
+                    testMonitor.wait();
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                    testMonitor.t2Exception = new RuntimeException(e);
+                    throw (RuntimeException) testMonitor.t2Exception;
+                }
+            }
+        }
+        SchemaBuilder.initCache();
+        Document doc = SchemaBuilderCacheTest.setupDocument();
+        XmlSchemaCollection schemaCol = SchemaBuilderCacheTest
+                .setupXmlSchemaCollection();
+        XmlSchema schema = schemaCol.read(doc, null);
+        if (schema == null) {
+            testMonitor.t2Exception = new Exception("Schema was null");
+        }
+
+        // If the cache is in use, it should not be null.
+        if (SchemaBuilderCacheTest.getResolvedSchemasHashtable() == null) {
+            testMonitor.t2Exception = new Exception("resolvedSchemas was 
null");
+        }
+        Map<String, SoftReference<XmlSchema>> threadHT = SchemaBuilderCacheTest
+                .getThreadResolvedSchemaHashtable();
+        if (threadHT == null) {
+            testMonitor.t2Exception = new Exception(
+                    "Thread resolvedSchemas was null");
+        }
+        if (threadHT.isEmpty()) {
+            testMonitor.t2Exception = new Exception(
+                    "Thread resolvedSchemas was empty");
+        }
+
+        // Issue our a clear on this TID, and now there should be no entires 
for
+        // it
+        SchemaBuilder.clearCache();
+        if (SchemaBuilderCacheTest.getResolvedSchemasHashtable() == null) {
+            testMonitor.t2Exception = new Exception(
+                    "resolvedSchemas was null after clear on TID");
+        }
+
+        threadHT = SchemaBuilderCacheTest.getThreadResolvedSchemaHashtable();
+        if (threadHT != null) {
+            testMonitor.t2Exception = new Exception(
+                    "Thread resolvedSchemas was not null after clear");
+        }
+
+        synchronized (testMonitor) {
+            testMonitor.t2SetupComplete = true;
+            testMonitor.notifyAll();
+        }
+    }
+}
+
+/**
+ * Test that the init done by Thread 1 does NOT cause the cache to be used by
+ * this thread which did not do an init.
+ */
+...@ignore
+class TestingRunnable3 implements Runnable {
+    MultithreadUpdateLockMonitor testMonitor;
+
+    public void run() {
+        synchronized (testMonitor) {
+            while (!testMonitor.t1SetupComplete) {
+                try {
+                    testMonitor.wait();
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                    testMonitor.t3Exception = new RuntimeException(e);
+                    throw (RuntimeException) testMonitor.t2Exception;
+                }
+            }
+        }
+        Document doc = SchemaBuilderCacheTest.setupDocument();
+        XmlSchemaCollection schemaCol = SchemaBuilderCacheTest
+                .setupXmlSchemaCollection();
+        XmlSchema schema = schemaCol.read(doc, null);
+        if (schema == null) {
+            testMonitor.t3Exception = new Exception("Schema was null");
+        }
+        Map<String, SoftReference<XmlSchema>> threadHT = SchemaBuilderCacheTest
+                .getThreadResolvedSchemaHashtable();
+        if (threadHT != null) {
+            testMonitor.t3Exception = new Exception(
+                    "Thread resolvedSchemas was not null");
+        }
+
+    }
+
+}

Propchange: 
webservices/commons/trunk/modules/XmlSchema/src/test/java/org/apache/ws/commons/schema/SchemaBuilderCacheTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
webservices/commons/trunk/modules/XmlSchema/src/test/java/org/apache/ws/commons/schema/SchemaBuilderCacheTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date


Reply via email to