Package org.exist.xquery

Source Code of org.exist.xquery.ConstructedNodesRecoveryTest

package org.exist.xquery;

import org.exist.collections.Collection;
import org.exist.collections.IndexInfo;
import org.exist.dom.DocumentImpl;
import org.exist.security.xacml.AccessContext;
import org.exist.source.StringSource;
import org.exist.storage.BrokerPool;
import org.exist.storage.DBBroker;
import org.exist.storage.lock.Lock;
import org.exist.storage.serializers.Serializer;
import org.exist.storage.txn.TransactionManager;
import org.exist.storage.txn.Txn;
import org.exist.test.TestConstants;
import org.exist.xmldb.XmldbURI;
import org.exist.xquery.value.Sequence;
import org.exist.util.Configuration;
import org.exist.util.serializer.SAXSerializer;
import org.exist.util.serializer.SerializerPool;

import org.xml.sax.InputSource;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.Properties;
import javax.xml.transform.OutputKeys;

import junit.framework.TestCase;
import junit.textui.TestRunner;

/** Tests for recovery of database corruption after constructed node operations (in-memory nodes)
* @author Adam Retter <adam.retter@devon.gov.uk>
*/
public class ConstructedNodesRecoveryTest extends TestCase
  private final static String xquery =
    "declare variable $categories := \n" +
    "  <categories>\n" +
    "    <category uid=\"1\">Fruit</category>\n" +
    "    <category uid=\"2\">Vegetable</category>\n" +
    "    <category uid=\"3\">Meat</category>\n" +
    "    <category uid=\"4\">Dairy</category>\n" +
    "  </categories>\n" +
    ";\n\n" +
   
    "for $category in $categories/category return\n" +
    "  element option {\n" +
    "    attribute value {\n" +
    "      $category/@uid\n" +
    "    },\n" +
    "    text { $category }\n" +
    "  }";

  private final static String expectedResults [] = {
    "Fruit",
    "Vegetable",
    "Meat",
    "Dairy"
  };
   
  private final static String testDocument =
    "<fruit>" +
      "<apple colour=\"green\"/>" +
      "<pear colour=\"green\"/>" +
      "<orange colour=\"orange\"/>" +
      "<dragonfruit colour=\"pink\"/>" +
      "<grapefruit colour=\"yellow\"/>" +
    "</fruit>";
 
  public static void main(String[] args)
  {
        TestRunner.run(ConstructedNodesRecoveryTest.class);
    }

  /**
   * Issues a query against constructed nodes and then corrupts the database (intentionally)
   */
  public void testConstructedNodesCorrupt()
  {
    constructedNodeQuery(true);
    }
   
  /**
   * Recovers from corruption (intentional) and then issues a query against constructed nodes
   */
  public void testConstructedNodesRecover()
  {
    constructedNodeQuery(false);
  }
 
  private void storeTestDocument(DBBroker broker, TransactionManager transact, String documentName) throws Exception
  {
    //create a transaction
    Txn transaction = transact.beginTransaction();
        assertNotNull(transaction);           
        System.out.println("Transaction started ...");
   
    //get the test collection
        Collection root = broker.getOrCreateCollection(transaction, TestConstants.TEST_COLLECTION_URI);
        assertNotNull(root);
        broker.saveCollection(transaction, root);
   
    //store test document
        IndexInfo info = root.validateXMLResource(transaction, broker, XmldbURI.create(documentName), testDocument);
        assertNotNull(info);
        root.store(transaction, broker, info, new InputSource(new StringReader(testDocument)), false);
       
        //commit the transaction
        transact.commit(transaction);
        System.out.println("Transaction commited ...");
  }
 
  private void createTempChildCollection(DBBroker broker, TransactionManager transact, String childCollectionName) throws Exception
  {
    //create a transaction
    Txn transaction = transact.beginTransaction();
        assertNotNull(transaction);           
        System.out.println("Transaction started ...");
   
    //get the test collection
        Collection root = broker.getOrCreateCollection(transaction, XmldbURI.TEMP_COLLECTION_URI.append(childCollectionName));
        assertNotNull(root);
        broker.saveCollection(transaction, root);
           
        //commit the transaction
        transact.commit(transaction);
        System.out.println("Transaction commited ...");
  }
 
  private void testDocumentIsValid(DBBroker broker, TransactionManager transact, String documentName) throws Exception
  {
    //create a transaction
    Txn transaction = transact.beginTransaction();
        assertNotNull(transaction);           
        System.out.println("Transaction started ...");
   
    //get the test collection
        Collection root = broker.getOrCreateCollection(transaction, TestConstants.TEST_COLLECTION_URI);
        assertNotNull(root);
        broker.saveCollection(transaction, root);
       
        //get the test document
        DocumentImpl doc = root.getDocumentWithLock(broker, XmldbURI.create(documentName), Lock.READ_LOCK);
       
        Serializer serializer = broker.getSerializer();
        serializer.reset();
        SAXSerializer sax = null;
        StringWriter writer = new StringWriter();
        sax = (SAXSerializer) SerializerPool.getInstance().borrowObject(SAXSerializer.class);
        Properties outputProperties = new Properties();
        outputProperties.setProperty(OutputKeys.INDENT, "no");
        outputProperties.setProperty(OutputKeys.ENCODING, "UTF-8");
        sax.setOutput(writer, outputProperties);
        serializer.setProperties(outputProperties);
        serializer.setSAXHandlers(sax, sax);
        serializer.toSAX(doc);
        SerializerPool.getInstance().returnObject(sax);
       
        assertEquals(testDocument, writer.toString());
       
        transact.commit(transaction);
  }
 
  private void testTempChildCollectionExists(DBBroker broker, TransactionManager transact, String childCollectionName) throws Exception
  {
    //create a transaction
    Txn transaction = transact.beginTransaction();
        assertNotNull(transaction);           
        System.out.println("Transaction started ...");
   
    //get the temp child collection
        Collection tempChildCollection = broker.getOrCreateCollection(transaction, XmldbURI.TEMP_COLLECTION_URI.append(childCollectionName));
        assertNotNull(tempChildCollection);
        broker.saveCollection(transaction, tempChildCollection);
       
        transact.commit(transaction);
  }
 
  /**
   * Performs a query against constructed nodes, with the option of forcefully corrupting the database
   *
   * @param forceCorruption  Should the database be forcefully corrupted
   */
  private void constructedNodeQuery(boolean forceCorruption)
  {
    BrokerPool.FORCE_CORRUPTION = forceCorruption;
      BrokerPool pool = null;       
      DBBroker broker = null;
     
      try
      {
        pool = startDB();
        assertNotNull(pool);
          broker = pool.get(pool.getSecurityManager().getSystemSubject());
         
          TransactionManager transact = pool.getTransactionManager();
            assertNotNull(transact);
           
            //only store the documents the first time
            if(forceCorruption)
            {
              //store a first test document
              storeTestDocument(broker, transact, "testcr1.xml");

              //store a second test document
              storeTestDocument(broker, transact, "testcr2.xml");
            }
           
            //create some child collections in TEMP collection
          createTempChildCollection(broker, transact, "testchild1");
          createTempChildCollection(broker, transact, "testchild2");
           
            //execute an xquery
          XQuery service = broker.getXQueryService();
          assertNotNull(service);
         
          CompiledXQuery compiled = service.compile(service.newContext(AccessContext.TEST), new StringSource(xquery));
          assertNotNull(compiled);
         
          Sequence result = service.execute(compiled, null);
          assertNotNull(result);
        
          assertEquals(expectedResults.length, result.getItemCount());
         
          for(int i = 0; i < result.getItemCount(); i++)
      {
        assertEquals(expectedResults[i], (String)result.itemAt(i).getStringValue());
      }
         
          //read the first test document
          testDocumentIsValid(broker, transact, "testcr1.xml");
         
          //read the second test document
          testDocumentIsValid(broker, transact, "testcr1.xml");
         
          //test the child collections exist
          testTempChildCollectionExists(broker, transact, "testchild1");
          testTempChildCollectionExists(broker, transact, "testchild2");
         
          transact.getJournal().flushToLog(true);
      }
      catch(Exception e)
      {           
          fail(e.getMessage());
          e.printStackTrace();
      }
      finally
      {
        if (pool != null) pool.release(broker);
      }
  }
 
  protected BrokerPool startDB() {
        try {
            Configuration config = new Configuration();
            BrokerPool.configure(1, 5, config);
            return BrokerPool.getInstance();
        } catch (Exception e) {           
            fail(e.getMessage());
        }
        return null;
    }

    protected void tearDown() {
        BrokerPool.stopAll(false);
    }
}
TOP

Related Classes of org.exist.xquery.ConstructedNodesRecoveryTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.