Java tutorial
// Copyright 2011 Google Inc. // // Licensed 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 com.google.enterprise.connector.db.diffing; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.common.io.ByteStreams; import com.google.enterprise.connector.db.DBConnectorType; import com.google.enterprise.connector.db.DBContext; import com.google.enterprise.connector.db.DBTestBase; import com.google.enterprise.connector.spi.Document; import com.google.enterprise.connector.spi.Property; import com.google.enterprise.connector.spi.RepositoryException; import com.google.enterprise.connector.spi.SimpleTraversalContext; import com.google.enterprise.connector.spi.TraversalContext; import com.google.enterprise.connector.spi.Value; import com.google.enterprise.connector.spiimpl.BinaryValue; import com.google.enterprise.connector.util.MimeTypeDetector; import com.google.enterprise.connector.util.diffing.DocumentHandle; import com.google.enterprise.connector.util.diffing.DocumentSnapshot; import com.google.enterprise.connector.util.diffing.TraversalContextManager; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.util.Arrays; import java.util.Iterator; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; public class DBSnapshotRepositoryTest extends DBTestBase { @Override protected void setUp() throws Exception { super.setUp(); runDBScript(CREATE_TEST_DB_TABLE); runDBScript(LOAD_TEST_DATA); } @Override protected void tearDown() throws Exception { try { runDBScript(DROP_TEST_DB_TABLE); } finally { super.tearDown(); } } private DBSnapshotRepository getObjectUnderTest(Map<String, String> configMap) { // Connector manager does this in production. TraversalContext tc = new SimpleTraversalContext(); MimeTypeDetector.setTraversalContext(tc); DBContext dbContext = getDbContext(configMap); TraversalContextManager traversalContextManager = new TraversalContextManager(); traversalContextManager.setTraversalContext(tc); RepositoryHandler repositoryHandler = RepositoryHandler.makeRepositoryHandlerFromConfig(dbContext, traversalContextManager); return new DBSnapshotRepository(repositoryHandler); } /** * TODO: Add URL and DocId maps with the required configMap entries * and corresponding test methods. */ private Map<String, String> getLobMap() { Map<String, String> newConfig = Maps.newHashMap(configMap); newConfig.put("extMetadataType", DBConnectorType.BLOB_CLOB); newConfig.put("lobField", "LNAME"); return newConfig; } public void testIterator() { DBSnapshotRepository out = getObjectUnderTest(configMap); Iterator<? extends DocumentSnapshot> it = out.iterator(); assertTrue(it.hasNext()); do { it.next(); } while (it.hasNext()); try { it.next(); fail("Expected a NoSuchElementException from an exhausted iterator."); } catch (NoSuchElementException expected) { } } public void testIteratorTwice() { DBSnapshotRepository out = getObjectUnderTest(configMap); int[] counts = { 0, 0 }; for (int i = 0; i < 2; i++) { Iterator<? extends DocumentSnapshot> it = out.iterator(); assertTrue("Pass " + (i + 1), it.hasNext()); do { counts[i]++; it.next(); } while (it.hasNext()); } assertEquals(counts[0], counts[1]); } public void testGetName() { assertEquals("com.google.enterprise.connector.db.diffing.DBSnapshotRepository", getObjectUnderTest(configMap).getName()); } private DocumentSnapshot getSnapshotUnderTest(Map<String, String> configMap) { return getObjectUnderTest(configMap).iterator().next(); } private DocumentSnapshot getDeserializedSnapshot(DocumentSnapshot snapshot) { String serialSnapshot = snapshot.toString(); DocumentSnapshot deserialSnapshot = new DBSnapshotFactory(getDbContext()).fromString(serialSnapshot); assertNotNull(deserialSnapshot); return deserialSnapshot; } private void testSnapshotLifecycle(Map<String, String> configMap) throws Exception { DocumentSnapshot snapshot = getSnapshotUnderTest(configMap); DocumentSnapshot deserialSnapshot = getDeserializedSnapshot(snapshot); // This is the core assertion, that a deserialized snapshot // compares as identical to the repository source snapshot. DocumentHandle update = snapshot.getUpdate(deserialSnapshot); if (update != null) { fail(update.toString()); } assertEquals(snapshot.getDocumentId(), deserialSnapshot.getDocumentId()); assertEquals(snapshot.toString(), deserialSnapshot.toString()); } public void testSnapshotLifecycle_default() throws Exception { testSnapshotLifecycle(configMap); } public void testSnapshotLifecycle_lob() throws Exception { testSnapshotLifecycle(getLobMap()); } private void testSnapshotUnsupportedOperation(Map<String, String> configMap) throws Exception { DocumentSnapshot snapshot = getSnapshotUnderTest(configMap); DocumentSnapshot deserialSnapshot = getDeserializedSnapshot(snapshot); try { DocumentHandle update = deserialSnapshot.getUpdate(snapshot); fail("Expected an UnsupportedOperationException exception"); } catch (UnsupportedOperationException expected) { } } public void testSnapshotUnsupportedOperation_default() throws Exception { testSnapshotUnsupportedOperation(configMap); } public void testSnapshotUnsupportedOperation_lob() throws Exception { testSnapshotUnsupportedOperation(getLobMap()); } public void testHandleLifecycle(Map<String, String> configMap) throws Exception { DocumentSnapshot snapshot = getSnapshotUnderTest(configMap); DocumentHandle handle = snapshot.getUpdate(null); assertNotNull(handle); Document doc = handle.getDocument(); assertNotNull(doc); Set<String> propertyNames = doc.getPropertyNames(); String serialHandle = handle.toString(); DocumentHandle deserialHandle = new DBHandleFactory().fromString(serialHandle); assertNotNull(deserialHandle); assertEquals("document ID", handle.getDocumentId(), deserialHandle.getDocumentId()); assertJsonEquals("serialization not value preserving", serialHandle, deserialHandle.toString()); Document recoveryDoc = deserialHandle.getDocument(); assertNotNull(recoveryDoc); // This is the core assertion, that a document from a deserialized // handle has the same properties as the original handle from the // SnapshotRepository. assertEquals("document from deserialized handle", propertyNames, recoveryDoc.getPropertyNames()); for (String propertyName : propertyNames) { assertPropertyEquals(propertyName, doc.findProperty(propertyName), recoveryDoc.findProperty(propertyName)); } } public void testHandleLifecycle_default() throws Exception { testHandleLifecycle(configMap); } public void testHandleLifecycle_lob() throws Exception { testHandleLifecycle(getLobMap()); } /** * Compares two JSON strings for equality. The order of the * name/value pairs in the string is not important (and that's why * this method is required, or we would just compare the strings * with each other). */ private void assertJsonEquals(String message, String expectedString, String actualString) throws JSONException { JSONObject expected = new JSONObject(expectedString); JSONObject actual = new JSONObject(actualString); Set<String> expectedNames = Sets.newHashSet(JSONObject.getNames(expected)); Set<String> actualNames = Sets.newHashSet(JSONObject.getNames(actual)); assertEquals(message, expectedNames, actualNames); for (String name : expectedNames) { assertEquals(message, expected.get(name), actual.get(name)); } } private void assertPropertyEquals(String message, Property expectedProperty, Property actualProperty) throws RepositoryException, IOException { assertNotNull(message, expectedProperty); assertNotNull(message, actualProperty); Value expectedValue = expectedProperty.nextValue(); Value actualValue = actualProperty.nextValue(); if (expectedValue instanceof BinaryValue) { assertTrue(actualValue.getClass().toString(), actualValue instanceof BinaryValue); assertBinaryValueEquals(message, (BinaryValue) expectedValue, (BinaryValue) actualValue); } else { assertEquals(message, expectedValue.toString(), actualValue.toString()); } } private void assertBinaryValueEquals(String message, BinaryValue expectedValue, BinaryValue actualValue) throws RepositoryException, IOException { assertTrue(message, Arrays.equals(ByteStreams.toByteArray(expectedValue.getInputStream()), ByteStreams.toByteArray(actualValue.getInputStream()))); } }