/** * Licensed to the Austrian Association for Software Tool Integration (AASTI) * under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright * ownership. The AASTI 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.openengsb.core.edb.jpa.internal; import static org.hamcrest.CoreMatchers.anyOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.notNullValue; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import org.junit.Test; import org.openengsb.core.api.model.QueryRequest; import org.openengsb.core.edb.api.EDBCommit; import org.openengsb.core.edb.api.EDBConstants; import org.openengsb.core.edb.api.EDBException; import org.openengsb.core.edb.api.EDBLogEntry; import org.openengsb.core.edb.api.EDBObject; import org.openengsb.core.edb.api.EDBObjectEntry; import com.google.common.collect.Lists; import com.google.common.collect.Maps; public class EDBFunctionTest extends AbstractEDBTest { @Test public void testOpenDatabase_shouldWork() throws Exception { assertThat(db, notNullValue()); } @Test public void testCommit_shouldWork() throws Exception { EDBObject obj = new EDBObject("Tester"); obj.putEDBObjectEntry("Test", "Hooray"); EDBCommit ci = db.createEDBCommit(Arrays.asList(obj), null, null); long time = db.commit(ci); obj = null; obj = db.getObject("Tester"); String hooray = obj.getString("Test"); assertThat(obj, notNullValue()); assertThat(hooray, notNullValue()); checkTimeStamps(Arrays.asList(time)); } @Test public void testGetCommits_shouldWork() throws Exception { EDBObject obj = new EDBObject("TestObject"); obj.putEDBObjectEntry("Bla", "Blabla"); EDBCommit ci = db.createEDBCommit(Arrays.asList(obj), null, null); long time = db.commit(ci); List<EDBCommit> commits1 = db.getCommitsByKeyValue("context", "testcontext"); List<EDBCommit> commits2 = db.getCommitsByKeyValue("context", "DoesNotExist"); assertThat(commits1.size(), is(1)); assertThat(commits2.size(), is(0)); checkTimeStamps(Arrays.asList(time)); } @Test(expected = EDBException.class) public void testGetInexistantObject_shouldThrowException() throws Exception { db.getObject("/this/object/does/not/exist"); } @SuppressWarnings("unchecked") @Test public void testGetHistoryAndCheckForElements_shouldWork() throws Exception { long time1 = 0; long time2 = 0; long time3 = 0; long time4 = 0; HashMap<String, EDBObjectEntry> data1 = new HashMap<String, EDBObjectEntry>(); putValue("Lock", "Key", data1); putValue("Door", "Bell", data1); putValue("Cat", "Spongebob", data1); EDBObject v1 = new EDBObject("/history/object", data1); EDBCommit ci = getEDBCommit(); ci.insert(createRandomTestObject("/useless/1")); ci.insert(v1); time1 = db.commit(ci); HashMap<String, EDBObjectEntry> data2 = (HashMap<String, EDBObjectEntry>) data1.clone(); putValue("Lock", "Smith", data2); EDBObject v2 = new EDBObject("/history/object", data2); ci = getEDBCommit(); ci.insert(createRandomTestObject("/useless/2")); ci.update(v2); time2 = db.commit(ci); HashMap<String, EDBObjectEntry> data3 = (HashMap<String, EDBObjectEntry>) data2.clone(); ci = getEDBCommit(); ci.insert(createRandomTestObject("/useless/3")); ci.insert(createRandomTestObject("/useless/4")); time3 = db.commit(ci); putValue("Cat", "Dog", data3); EDBObject v3 = new EDBObject("/history/object", data3); ci = getEDBCommit(); ci.update(v3); ci.insert(createRandomTestObject("/useless/5")); time4 = db.commit(ci); List<EDBObject> history = db.getHistory("/history/object"); boolean ordered = true; for (int i = 1; i < 3; i++) { if (history.get(i - 1).getTimestamp() > history.get(i).getTimestamp()) { ordered = false; } } assertThat(ordered, is(true)); assertThat(history.get(0).getString("Lock"), is("Key")); assertThat(history.get(0).getString("Cat"), is("Spongebob")); assertThat(history.get(1).getString("Lock"), is("Smith")); assertThat(history.get(1).getString("Cat"), is("Spongebob")); assertThat(history.get(2).getString("Lock"), is("Smith")); assertThat(history.get(2).getString("Cat"), is("Dog")); checkTimeStamps(Arrays.asList(time1, time2, time3, time4)); } @Test public void testHistoryOfDeletion_shouldWork() throws Exception { EDBCommit ci = getEDBCommit(); ci.insert(createRandomTestObject("/deletion/1")); long time1 = db.commit(ci); ci = getEDBCommit(); ci.delete("/deletion/1"); long time2 = db.commit(ci); List<EDBObject> history = db.getHistory("/deletion/1"); assertThat(history.size(), is(2)); assertThat(history.get(0).isDeleted(), is(false)); assertThat(history.get(1).isDeleted(), is(true)); checkTimeStamps(Arrays.asList(time1, time2)); } @Test public void testGetLog_shouldWork() throws Exception { long time1 = 0; long time2 = 0; long time3 = 0; long time4 = 0; Map<String, EDBObjectEntry> data1 = new HashMap<String, EDBObjectEntry>(); putValue("Burger", "Salad", data1); putValue("Bla", "Blub", data1); putValue("Cheese", "Butter", data1); EDBObject v1 = new EDBObject("/history/test/object", data1); EDBCommit ci = getEDBCommit(); ci.insert(createRandomTestObject("/useless/test/1")); ci.insert(createRandomTestObject("/deletion/test/1")); ci.insert(v1); time1 = db.commit(ci); Map<String, EDBObjectEntry> data2 = Maps.newHashMap(data1); putValue("Burger", "Meat", data2); EDBObject v2 = new EDBObject("/history/test/object", data2); ci = getEDBCommit(); ci.insert(createRandomTestObject("/useless/test/2")); ci.delete("/deletion/test/1"); ci.update(v2); time2 = db.commit(ci); Map<String, EDBObjectEntry> data3 = Maps.newHashMap(data2); ci = getEDBCommit(); ci.insert(createRandomTestObject("/useless/test/3")); ci.insert(createRandomTestObject("/useless/test/4")); time3 = db.commit(ci); putValue("Cheese", "Milk", data3); EDBObject v3 = new EDBObject("/history/test/object", data3); ci = getEDBCommit(); ci.update(v3); ci.insert(createRandomTestObject("/useless/test/5")); time4 = db.commit(ci); List<EDBLogEntry> log = db.getLog("/history/test/object", time1, time4); assertThat(log.size(), is(3)); checkTimeStamps(Arrays.asList(time1, time2, time3, time4)); } @Test public void testDiff_shouldWork() throws Exception { long time1 = 0; long time2 = 0; long time3 = 0; Map<String, EDBObjectEntry> data1 = new HashMap<String, EDBObjectEntry>(); putValue("KeyA", "Value A 1", data1); putValue("KeyB", "Value B 1", data1); putValue("KeyC", "Value C 1", data1); EDBObject v1 = new EDBObject("/diff/object", data1); EDBCommit ci = getEDBCommit(); ci.insert(v1); time1 = db.commit(ci); Map<String, EDBObjectEntry> data2 = Maps.newHashMap(data1); putValue("KeyD", "Value D 1", data2); putValue("KeyA", "Value A 2", data2); EDBObject v2 = new EDBObject("/diff/object", data2); ci = getEDBCommit(); ci.update(v2); time2 = db.commit(ci); Map<String, EDBObjectEntry> data3 = Maps.newHashMap(data2); data3.remove("KeyB"); putValue("KeyC", "Value C 3", data3); EDBObject v3 = new EDBObject("/diff/object", data3); ci = getEDBCommit(); ci.update(v3); time3 = db.commit(ci); checkTimeStamps(Arrays.asList(time1, time2, time3)); Diff diffAb = db.getDiff(time1, time2); Diff diffBc = db.getDiff(time2, time3); Diff diffAc = db.getDiff(time1, time3); assertThat(diffAb.getDifferenceCount(), is(1)); assertThat(diffBc.getDifferenceCount(), is(1)); assertThat(diffAc.getDifferenceCount(), is(1)); } @Test public void testGetResurrectedOIDs_shouldWork() throws Exception { Map<String, EDBObjectEntry> data1 = new HashMap<String, EDBObjectEntry>(); putValue("KeyA", "Value A 1", data1); EDBObject v1 = new EDBObject("/ress/object", data1); EDBCommit ci = getEDBCommit(); ci.insert(v1); long time1 = db.commit(ci); v1 = new EDBObject("/ress/object2", data1); ci = getEDBCommit(); ci.insert(v1); ci.delete("/ress/object"); long time2 = db.commit(ci); v1 = new EDBObject("/ress/object", data1); ci = getEDBCommit(); ci.delete("/ress/object2"); ci.update(v1); long time3 = db.commit(ci); List<String> oids = db.getResurrectedOIDs(); assertThat(oids.contains("/ress/object"), is(true)); assertThat(oids.contains("/ress/object2"), is(false)); checkTimeStamps(Arrays.asList(time1, time2, time3)); } @Test(expected = EDBException.class) public void testCommitTwiceSameCommit_shouldThrowError() throws Exception { Map<String, EDBObjectEntry> data1 = new HashMap<String, EDBObjectEntry>(); putValue("KeyA", "Value A 1", data1); EDBObject v1 = new EDBObject("/fail/object", data1); EDBCommit ci = getEDBCommit(); ci.insert(v1); db.commit(ci); db.commit(ci); } @Test public void testCommitEDBObjectsInsert_shouldWork() throws Exception { EDBObject object = new EDBObject("/commit/test/insert/1"); object.putEDBObjectEntry("bla", "blub"); List<EDBObject> inserts = new ArrayList<EDBObject>(); inserts.add(object); commitObjects(inserts, null, null); object = db.getObject("/commit/test/insert/1"); assertThat(object.getString("bla"), is("blub")); assertThat(object.getObject(EDBConstants.MODEL_VERSION, Integer.class), is(1)); } @Test(expected = EDBException.class) public void testCommitEDBObjectsInsertDouble_shouldThrowException() throws Exception { EDBObject object = new EDBObject("/commit/test/insert/2"); List<EDBObject> inserts = new ArrayList<EDBObject>(); inserts.add(object); commitObjects(inserts, null, null); commitObjects(inserts, null, null); } @Test(expected = EDBException.class) public void testIfConflictDetectionIsWorking_shouldThrowException() throws Exception { EDBObject object = new EDBObject("/commit/test/insert/3"); object.putEDBObjectEntry("bla", "blub"); List<EDBObject> inserts = new ArrayList<EDBObject>(); inserts.add(object); commitObjects(inserts, null, null); object = db.getObject("/commit/test/insert/3"); object.putEDBObjectEntry(EDBConstants.MODEL_VERSION, Integer.valueOf(0)); object.putEDBObjectEntry("test", "test"); commitObjects(inserts, Arrays.asList(object), null); } @Test public void testCommitEDBObjectsUpdate_shouldWork() throws Exception { EDBObject object = new EDBObject("/commit/test/update/1"); object.putEDBObjectEntry("testkey", "testvalue"); List<EDBObject> objects = new ArrayList<EDBObject>(); objects.add(object); commitObjects(objects, null, null); EDBObject first = db.getObject("/commit/test/update/1"); objects.clear(); object.putEDBObjectEntry("testkey", "testvalue1"); objects.add(object); commitObjects(null, objects, null); EDBObject second = db.getObject("/commit/test/update/1"); assertThat(first.getObject(EDBConstants.MODEL_VERSION, Integer.class), is(1)); assertThat(first.getString("testkey"), is("testvalue")); assertThat(second.getObject(EDBConstants.MODEL_VERSION, Integer.class), is(2)); assertThat(second.getString("testkey"), is("testvalue1")); } @Test(expected = EDBException.class) public void testCommitEDBObjectsUpdateVerstionConflict_shouldThrowException() throws Exception { EDBObject object = new EDBObject("/commit/test/update/2"); List<EDBObject> objects = new ArrayList<EDBObject>(); objects.add(object); commitObjects(objects, null, null); object.putEDBObjectEntry(EDBConstants.MODEL_VERSION, Integer.valueOf(0)); object.putEDBObjectEntry("test", "test"); commitObjects(null, objects, null); } @Test(expected = EDBException.class) public void testCommitEDBObjectsUpdateVerstionConflict2_shouldThrowException() throws Exception { EDBObject object = new EDBObject("/commit/test/update/3"); commitObjects(Arrays.asList(object), null, null); EDBObject receive1 = db.getObject("/commit/test/update/3"); EDBObject receive2 = db.getObject("/commit/test/update/3"); receive1.putEDBObjectEntry("test1", "test1"); receive2.putEDBObjectEntry("test1", "test2"); commitObjects(null, Arrays.asList(receive1), null); commitObjects(null, Arrays.asList(receive2), null); } @Test public void testCommitEDBObjectsDelete_shouldWork() throws Exception { EDBObject object = new EDBObject("/commit/test/delete/1"); List<EDBObject> objects = new ArrayList<EDBObject>(); objects.add(object); commitObjects(objects, null, null); commitObjects(null, null, objects); EDBObject entry = db.getObject("/commit/test/delete/1"); assertThat(entry.isDeleted(), is(true)); } @Test(expected = EDBException.class) public void testCommitEDBObjectsDeleteNonExisting_shouldThrowException() throws Exception { EDBObject object = new EDBObject("/commit/test/delete/2"); List<EDBObject> objects = new ArrayList<EDBObject>(); objects.add(object); commitObjects(null, null, objects); } @Test(expected = EDBException.class) public void testCommitEDBObjectsDeleteAlreadyDeleted_shouldThrowException() throws Exception { EDBObject object = new EDBObject("/commit/test/delete/3"); List<EDBObject> objects = new ArrayList<EDBObject>(); objects.add(object); commitObjects(objects, null, null); commitObjects(null, null, objects); commitObjects(null, null, objects); } @Test public void testIfOtherTypesThanStringWorks_shouldProcessInteger() throws Exception { EDBObject object = new EDBObject("test/type/integer"); object.putEDBObjectEntry("value", Integer.valueOf(42)); commitObjects(Arrays.asList(object), null, null); object = db.getObject("test/type/integer"); Object value = object.getObject("value"); assertThat(value.getClass().getName(), is(Integer.class.getName())); assertThat((Integer) value, is(42)); } @Test public void testIfOtherTypesThanStringWorks_shouldProcessBoolean() throws Exception { EDBObject object = new EDBObject("test/type/boolean"); object.putEDBObjectEntry("value", Boolean.TRUE); commitObjects(Arrays.asList(object), null, null); object = db.getObject("test/type/boolean"); Object value = object.getObject("value"); assertThat(value.getClass().getName(), is(Boolean.class.getName())); assertThat((Boolean) value, is(Boolean.TRUE)); } @Test public void testIfOtherTypesThanStringWorks_shouldProcessDate() throws Exception { EDBObject object = new EDBObject("test/type/date"); Date date = new Date(); object.putEDBObjectEntry("value", date); commitObjects(Arrays.asList(object), null, null); object = db.getObject("test/type/date"); Object value = object.getObject("value"); assertThat(value.getClass().getName(), is(Date.class.getName())); assertThat((Date) value, is(date)); } @Test public void testIfCreatedCommitContainsRevisionNumber_shouldReturnNotNull() throws Exception { EDBCommit ci = getEDBCommit(); assertThat(ci.getRevisionNumber(), notNullValue()); } @Test(expected = EDBException.class) public void testIfWrongParentCausesCommitError_shouldThrowException() throws Exception { db.commit(getEDBCommit()); // add one entry so that there is actually a head EDBCommit ci = getEDBCommit(); ci.insert(createRandomTestObject("/wrongparent/1")); EDBCommit ci2 = getEDBCommit(); ci2.insert(createRandomTestObject("/wrongparent/2")); db.commit(ci2); db.commit(ci); } @SuppressWarnings("unchecked") @Test public void testDeleteCommit_shouldDeleteCommit() throws Exception { UUID preCommit1Revision = db.getCurrentRevisionNumber(); EDBObject eo1 = createRandomTestObject("deleteCommitTest/1"); EDBObject eo2 = createRandomTestObject("deleteCommitTest/2"); commitObjects(Lists.newArrayList(eo1, eo2), null, null); UUID preCommit2Revision = db.getCurrentRevisionNumber(); EDBObject eo3 = createRandomTestObject("deleteCommitTest/3"); commitObjects(Lists.newArrayList(eo3), null, Lists.newArrayList(eo1, eo2)); UUID postCommit2Revision = db.getCurrentRevisionNumber(); List<EDBObject> result = db.query(QueryRequest.create()); assertThat(result.size(), is(1)); db.deleteCommit(postCommit2Revision); UUID postDelete1Revision = db.getCurrentRevisionNumber(); assertThat(postDelete1Revision, is(preCommit2Revision)); result = db.query(QueryRequest.create()); assertThat(result.size(), is(2)); assertThat(result.get(0).getOID(), anyOf(is(eo1.getOID()), is(eo2.getOID()))); assertThat(result.get(1).getOID(), anyOf(is(eo1.getOID()), is(eo2.getOID()))); db.deleteCommit(preCommit2Revision); UUID postDelete2Revision = db.getCurrentRevisionNumber(); assertThat(postDelete2Revision, is(preCommit1Revision)); result = db.query(QueryRequest.create()); assertThat(result.size(), is(0)); } @Test(expected = EDBException.class) public void testDeleteWithNullRevision_shouldThrowException() { db.deleteCommit(null); } @Test(expected = EDBException.class) public void testDeleteCommitWithWrongRevision_shouldThrowException() { db.deleteCommit(UUID.randomUUID()); } }