/*
* 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.
*
* $Id: CollectionTest.java 530621 2007-04-20 03:08:08Z vgritsenko $
*/
package org.apache.xindice.core;
import org.apache.xindice.core.data.NodeSet;
import org.apache.xindice.core.query.XPathQueryResolver;
import org.apache.xindice.util.Configuration;
import org.apache.xindice.util.XindiceException;
import org.apache.xindice.xml.TextWriter;
import org.apache.xindice.xml.SymbolTable;
import org.apache.xindice.xml.dom.DOMParser;
import org.apache.xindice.xml.dom.DOMCompressor;
import org.apache.xindice.xml.dom.DocumentImpl;
import junit.framework.TestCase;
import org.w3c.dom.Document;
/**
* Tests Xindice Core API (org.apache.xindice.core.Database,
* org.apache.xindice.core.Collection)
*
* @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
* @version $Revision: 530621 $, $Date: 2007-04-19 23:08:08 -0400 (Thu, 19 Apr 2007) $
*/
public class CollectionTest extends TestCase {
private static final String XML = "<test string='true'>This is a test document</test>";
private Database db;
private Collection collection;
public CollectionTest(String name) {
super(name);
}
public void setUp() throws Exception {
String name = getClass().getName();
db = new Database();
db.setConfig(new Configuration(DOMParser.toDocument(DatabaseTest.DATABASE)));
collection = db.createCollection(name, new Configuration(
DOMParser.toDocument(
"<collection compressed=\"true\" name=\"" + name + "\" inline-metadata=\"true\">" +
"<filer class=\"org.apache.xindice.core.filer.BTreeFiler\" />" +
"</collection>"), false
));
}
public void tearDown() throws Exception {
db.dropCollection(collection);
db.close();
}
private byte[] generateBinary() {
byte[] in = new byte[256];
for (int i = 0; i < in.length; i++) {
in[i] = (byte) (Math.random() * 256);
}
return in;
}
/**
* Tests insertBinary, getBinary, remove
*/
public void testBinary() throws Exception {
byte[] in = generateBinary();
collection.insertBinary("binary", in);
byte[] out = collection.getBinary("binary");
assertNotNull("Binary must be in there", out);
assertEquals("The size of the found and saved binary should be the same", in.length, out.length);
for (int i = 0; i < in.length; ++i) {
assertEquals("The resources differ in byte " + i, in[i], out[i]);
}
collection.remove("binary");
out = collection.getBinary("binary");
assertNull("Binary should have been removed", out);
}
/**
* Tests insertDocument, getDocument, remove
*/
public void testDocument() throws Exception {
Document in = collection.getConfig().getElement().getOwnerDocument();
String inStr = TextWriter.toString(in);
collection.insertDocument("document", in);
Document out = collection.getDocument("document");
assertNotNull("Document must be in there", out);
String outStr = TextWriter.toString(out);
assertEquals("Documents do not match", inStr, outStr);
collection.remove("document");
out = collection.getDocument("document");
assertNull("Document should have been removed", out);
}
/**
* Test querying of mixed content (XML and binary) collection
*/
public void testMixedContent() throws Exception {
Document document = DOMParser.toDocument(XML);
byte[] binary = generateBinary();
collection.insertDocument("document", document);
collection.insertBinary("binary", binary);
XPathQueryResolver service = new XPathQueryResolver();
NodeSet resultSet = service.query(collection, "/test", null, null);
int resultCount = 0;
while (resultSet.hasMoreNodes()) {
resultSet.getNextNode();
resultCount++;
}
assertEquals(1, resultCount);
}
public void testCompressedDocument() throws Exception {
// Compress the document with own symbol table
Document document = DOMParser.toDocument(XML);
SymbolTable symbols = new SymbolTable();
byte[] data = DOMCompressor.compress(document, symbols);
Document compressedDoc = new DocumentImpl(data, symbols, null);
// Store it in the collection
collection.insertDocument("document", compressedDoc);
Document res = collection.getDocument("document");
// Must match
String expected = TextWriter.toString(document);
String actual = TextWriter.toString(res);
assertEquals("Documents do not match", expected, actual);
}
public void testConcurrentCreateCollection() throws Exception {
final String name = "create";
try {
final int THREADS = 10;
Thread[] threads = new Thread[THREADS];
final Counter count = new Counter();
for (int i = 0; i < THREADS; i++) {
threads[i] = new Thread() {
public void run() {
try {
db.createCollection(name, new Configuration(
DOMParser.toDocument(
"<collection compressed='true' name='" + name + "' inline-metadata='true'>" +
" <filer class='org.apache.xindice.core.filer.BTreeFiler' />" +
"</collection>"), false
));
} catch (DBException e) {
if (e.faultCode == FaultCodes.COL_DUPLICATE_COLLECTION) {
count.incCount();
} else {
throw new RuntimeException("Failure: " + e);
}
} catch (XindiceException e) {
// ignore
}
}
};
}
for (int i = 0; i < THREADS; i++) {
threads[i].start();
}
for (int i = 0; i < THREADS; i++) {
threads[i].join();
}
assertEquals(THREADS - 1, count.getCount());
} finally {
Collection col = db.getCollection(name);
if (col != null) {
db.dropCollection(col);
}
}
}
private class Counter {
int count;
public int getCount() {
return count;
}
public synchronized void incCount() {
count++;
}
}
// FIXME Define semantics of document cache, and write tests for it
// public void testDocumentCache() throws Exception {
// Document in = collection.getConfig().getElement().getOwnerDocument();
// collection.insertDocument("document", in);
//
// Document out1 = collection.getDocument("document");
// Document out2 = collection.getDocument("document");
// assertTrue(out1 == out2);
// }
}