package com.google.code.joto.eventrecorder.impl; import java.io.File; import java.io.Serializable; import java.util.List; import java.util.Random; import junit.framework.TestCase; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.code.joto.eventrecorder.RecordEventData; import com.google.code.joto.eventrecorder.RecordEventStore; import com.google.code.joto.eventrecorder.RecordEventSummary; import com.google.code.joto.testobj.TestObjFactory; /** * */ public class AbstractRecordEventStoreTestHelper extends TestCase { private static final Logger log = LoggerFactory.getLogger(AbstractRecordEventStoreTestHelper.class); private File targetTestDir; public AbstractRecordEventStoreTestHelper(String name) { super(name); } public void setUp() { targetTestDir = new File("target/test"); if (!targetTestDir.exists()) { targetTestDir.mkdirs(); } } protected File getTargetTestDir() { return targetTestDir; } protected File getTestFileToCreate(String fileName) { File file = new File(targetTestDir, fileName); if (file.exists()) { file.delete(); } return file; } protected void deleteTestFile(File file) { file.delete(); } protected void doTestWrite1CloseRead(RecordEventStore eventStore) { generateEvent(eventStore, 0); checkGetEvents(eventStore, 1, 2, true); eventStore.close(); eventStore.open("r"); checkGetEvents(eventStore, 1, 2, true); eventStore.close(); eventStore.open("ra"); checkGetEvents(eventStore, 1, 2, true); } protected void doTestReadWriteMany(RecordEventStore eventStore, boolean canPurge) { int count = 0; RecordEventData evt1 = generateEvent(eventStore, 0); count++; assertNotNull(evt1); assertEquals(1, evt1.getEventId()); assertEquals(1, eventStore.getFirstEventId()); assertEquals(count+1, eventStore.getLastEventId()); assertEquals(count, eventStore.getEventsCount()); RecordEventData evt2 = generateEvent(eventStore, 0); count++; assertNotNull(evt2); assertEquals(2, evt2.getEventId()); assertEquals(count+1, eventStore.getLastEventId()); assertEquals(1, eventStore.getFirstEventId()); assertEquals(count, eventStore.getEventsCount()); generateEvents(eventStore, 1000, 0); count += 1000; assertEquals(count+1, eventStore.getLastEventId()); if (!canPurge) { assertEquals(1, eventStore.getFirstEventId()); assertEquals(count, eventStore.getEventsCount()); } // test re-reading past events int checkFromId = (!canPurge)? 1 : eventStore.getFirstEventId(); checkGetEvents(eventStore, checkFromId, count+1, true); // equivalent to ... checkGetEvents(eventStore, 0, -1); if (!canPurge) { checkGetEvents(eventStore, 5, 10, true); } else { int checkFromId2 = Math.min(checkFromId + 5, count); int checkToId2 = Math.min(checkFromId2 + 10, count+1); if (checkFromId2 < checkToId2) { checkGetEvents(eventStore, checkFromId2, checkToId2, true); } } // alternate writing and re-reading Random rand = new Random(0); for (int i = 1; i < 5; i++) { int writeCount = i*2; generateEvents(eventStore, writeCount, 0); count += writeCount; assertEquals(count+1, eventStore.getLastEventId()); if (!canPurge) { assertEquals(count, eventStore.getEventsCount()); } int firstEventId = eventStore.getFirstEventId(); int lastEventId = eventStore.getLastEventId(); if (lastEventId != firstEventId) { int readFromEventId = firstEventId + rand.nextInt(eventStore.getEventsCount()); if (count > readFromEventId) { int readToEventId = readFromEventId + rand.nextInt(count - readFromEventId); checkGetEvents(eventStore, readFromEventId, readToEventId, true); } } } // close and reopen in readonly eventStore.close(); eventStore.open("r"); // re-read int readFromEventId = eventStore.getFirstEventId(); checkGetEvents(eventStore, readFromEventId, count, true); } protected List<RecordEventSummary> checkGetEvents(RecordEventStore eventStore, int readFromEventId, int readToEventId, boolean checkGetEventData ) { if (readFromEventId == 0) { readFromEventId = 1; } if (readToEventId == -1) { readToEventId = eventStore.getLastEventId(); } if (readFromEventId < eventStore.getFirstEventId()) { readFromEventId = eventStore.getFirstEventId(); } if (readToEventId > eventStore.getLastEventId()) { readToEventId = eventStore.getLastEventId(); } List<RecordEventSummary> res = eventStore.getEvents(readFromEventId, readToEventId); assertNotNull(res); int readCount = readToEventId - readFromEventId; assertEquals(readCount, res.size()); if (readCount > 0) { assertEquals(readFromEventId, res.get(0).getEventId()); if (readCount > 1) { assertEquals(readFromEventId+1, res.get(1).getEventId()); } if (readCount > 2) { assertEquals(readFromEventId+2, res.get(2).getEventId()); assertEquals(readToEventId-3, res.get(readCount-3).getEventId()); } if (readCount > 1) { assertEquals(readToEventId-2, res.get(readCount-2).getEventId()); } assertEquals(readToEventId-1, res.get(readCount-1).getEventId()); } if (checkGetEventData) { checkGetEventDataList(eventStore, res); } return res; } protected void checkGetEventData(RecordEventStore eventStore, RecordEventSummary eventSummary) { RecordEventData eventData = eventStore.getEventData(eventSummary); assertNotNull(eventData); } protected void checkGetEventDataList(RecordEventStore eventStore, List<RecordEventSummary> events) { for (RecordEventSummary e : events) { checkGetEventData(eventStore, e); } // toadd: also test in random order? } protected void generateEvents(RecordEventStore eventStore, int count, int randSeed) { for (int i = 0; i < count; i++) { generateEvent(eventStore, randSeed++); } } protected RecordEventData generateEvent(RecordEventStore eventStore, int randSeed) { RecordEventSummary e = RecordEventSummary.snewDefault( "testEventType" + (randSeed%5), "testEventSubType" + (randSeed%10), "testClass" + (randSeed%3), "testMeth" + (randSeed%20)); Serializable objData = TestObjFactory.createAnySerializableBean(randSeed); RecordEventData res = eventStore.addEvent(e, objData); return res; } protected void generateEvents_SimpleIntFieldA(RecordEventStore eventStore, int count, int randSeed) { for (int i = 0; i < count; i++) { generateEvent_SimpleIntFieldA(eventStore, randSeed++); } } protected RecordEventData generateEvent_SimpleIntFieldA(RecordEventStore eventStore, int randSeed) { RecordEventSummary e = RecordEventSummary.snewDefault( "testEventType" + (randSeed%5), "testEventSubType" + (randSeed%10), "testClass" + (randSeed%3), "testMeth" + (randSeed%20)); Serializable objData = TestObjFactory.createSimpleIntFieldA(); RecordEventData res = eventStore.addEvent(e, objData); return res; } protected void doRunBenchmarkWriteSimple(RecordEventStore eventStore, int repeatCount, int writeCount) { long totalAddNanos = 0; long totalFlushNanos = 0; for (int i = 0; i < repeatCount; i++) { long nanos1 = System.nanoTime(); generateEvents_SimpleIntFieldA(eventStore, writeCount, 0); long nanos2 = System.nanoTime(); eventStore.flush(); long nanos3 = System.nanoTime(); totalAddNanos += (nanos2 - nanos1); totalFlushNanos += (nanos3 - nanos2); // int millis10 = (int) (10*nanos / 1000000); // log.info("write+flush " + writeCount + " events with simple obj, " // + "took:" + (millis10*0.1) + " ms/" + writeCount // + ", " + (millis10*0.1/writeCount) + " ms/u" // ); } log.info("bench FileRecordEventStore: repeat " + repeatCount + " x write+flush " + writeCount + " events with simple obj\n" + " total time: " + formatNanosTotalTime(totalAddNanos + totalFlushNanos, repeatCount, writeCount) + "\n" + " time for addEvent(): " + formatNanosTotalTime(totalAddNanos, repeatCount, writeCount) + "\n" + " time for flush(): " + formatNanosTotalTime(totalFlushNanos, repeatCount, writeCount) + "\n" ); } protected String formatNanosTotalTime(long totalNanos, int repeatCount, int size) { int totalMillis = (int) (totalNanos / 1000000); String res = totalMillis + " ms" + ", " + (totalMillis/repeatCount) + " ms/" + size + " in avg" + ", " + ((double)totalMillis/repeatCount/size) + " ms/u in avg"; return res; } }