001 package nl.cwi.sen1.visbase.rstorecontainer;
002
003 import java.io.ByteArrayInputStream;
004 import java.io.File;
005 import java.io.FileInputStream;
006 import java.io.InputStream;
007 import java.io.InputStreamReader;
008 import java.net.URISyntaxException;
009 import java.net.URL;
010 import java.util.ArrayList;
011
012 import junit.framework.TestCase;
013 import nl.cwi.sen1.relationstores.types.RElem;
014 import nl.cwi.sen1.relationstores.types.RStore;
015 import nl.cwi.sen1.relationstores.types.RTuple;
016 import nl.cwi.sen1.relationstores.types.RTupleRtuples;
017 import nl.cwi.sen1.visbase.rstorecontainer.datatypes.FactInfo;
018
019 import org.apache.commons.logging.Log;
020 import org.apache.commons.logging.LogFactory;
021
022 import aterm.ATerm;
023 import aterm.ATermInt;
024 import aterm.ATermList;
025 import aterm.pure.ATermApplImpl;
026 import aterm.pure.PureFactory;
027
028 /**
029 * JUnit Testcase used to test RStoreContainer.
030 *
031 * Some tests depend on the file.
032 *
033 * @c simple_graph_test.rstore.
034 *
035 * This file should be stored in the same package as this class.
036 *
037 * @author Ricardo Lindooren
038 * @author Arend van Beelen (reviewer)
039 * @date 2007-02-13
040 */
041 public class RStoreContainerTest extends TestCase {
042
043 private RStoreContainer m_container;
044
045 private static final Log m_log = LogFactory
046 .getLog(RStoreContainerTest.class);
047
048 private final static String NAME_OF_TESTFILE = "simple_graph_test.rstore";
049
050 private final static String NAME_OF_UPDATED_TESTFILE = "simple_graph_test_updated.rstore";
051
052 @Override
053 protected void setUp() throws Exception {
054 super.setUp();
055
056 m_container = new RStoreContainer();
057 }
058
059 @Override
060 protected void tearDown() throws Exception {
061 super.tearDown();
062
063 m_container = null;
064 }
065
066 /**
067 * Opens the reference to the Test File (DTF).
068 *
069 * Creates an InputStream (IS) based on the DTF.
070 *
071 * Reads bytes from the IS and prints these to System.out till there are no
072 * more bytes left.
073 *
074 * @author Ricardo Lindooren
075 * @author Arend van Beelen (reviewer)
076 * @date 2007-02-13
077 */
078 public void testInputStreamFromFile() throws Exception {
079
080 // destructive test, null input
081 RuntimeException runtimeException = null;
082 try {
083 m_container.inputStreamFromFile(null);
084 } catch (RuntimeException exception) {
085 runtimeException = exception;
086 }
087 assertNotNull("Should throw RuntimeException when File input is null",
088 runtimeException);
089
090 // normal use test, using the testfile
091 File testFile = getTestFile();
092 assertNotNull("TestFile should not be null", testFile);
093 assertTrue("TestFile should be readable", testFile.canRead());
094
095 // create InputStream from File
096 InputStream inputStream = m_container.inputStreamFromFile(testFile);
097 assertNotNull("Inputstream created from file should not be null",
098 inputStream);
099
100 // Read InputStream
101 InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
102 assertNotNull(
103 "InputStreamReader used to read InputStream should not be null",
104 inputStreamReader);
105
106 // read contents from input stream (bitwise and unbuffered, so this is
107 // slow, but the testfile is small)
108 int numBytesRead = -1;
109 StringBuilder stringBuilder = new StringBuilder();
110 while (true) {
111 numBytesRead = inputStreamReader.read();
112
113 if (numBytesRead == -1) {
114 break;
115 }
116
117 stringBuilder.append((char) numBytesRead);
118 }
119
120 if (m_log.isDebugEnabled()) {
121 m_log.debug("Data from InputStream: \n\n\t"
122 + stringBuilder.toString() + "\n");
123 }
124
125 inputStreamReader.close();
126 inputStream.close();
127 }
128
129 /**
130 * Parses the RStore data from the test file and checks the expected values.
131 *
132 * @author Ricardo Lindooren
133 * @author Arend van Beelen (reviewer)
134 * @date 2007-02-14
135 */
136 public void testParseRstore() throws Exception {
137
138 // destructive test, null input
139 RuntimeException runtimeException = null;
140 try {
141 m_container.parseRStore(null);
142 } catch (RuntimeException exception) {
143 runtimeException = exception;
144 }
145 assertNotNull("Should throw RuntimeException when InputStream is null",
146 runtimeException);
147
148 // destrucive test, wrong InputStream
149 RStoreParseException rpex = null;
150 try {
151 byte[] fakeByteArray = new byte[1];
152
153 InputStream defectiveInputStream = new ByteArrayInputStream(fakeByteArray);
154 m_container.parseRStore(defectiveInputStream);
155 } catch (RStoreParseException exx) {
156 rpex = exx;
157 }
158 assertNotNull("Should throw RStoreParseException when InputStream is not correct",
159 rpex);
160
161 // normal use test, using the testfile
162 File testFile = getTestFile();
163 assertTrue("TestFile should be readable", testFile.canRead());
164
165 InputStream inputStream = m_container.inputStreamFromFile(testFile);
166 assertNotNull("Inputstream created from file should not be null",
167 inputStream);
168
169 RStore parsedRStore = m_container.parseRStore(inputStream);
170 assertNotNull("Parsed RStore should not be null", parsedRStore);
171
172 RTupleRtuples rTuples = parsedRStore.getRtuples();
173 assertEquals("There should be exactly one (1) RTuple in the test file",
174 1, rTuples.getLength());
175
176 RTuple rTuple = rTuples.getRTupleAt(0);
177 assertNotNull("There should be a RTuple in the test file", rTuple);
178
179 FactInfo factInfo = new FactInfo(1, rTuple);
180 final String factName = factInfo.getName();
181 assertEquals("Name of RTuple not equal to expected value",
182 "SIMPLE_GRAPH", factName);
183
184 final String relationType = factInfo.getType();
185 assertEquals("Type of RTuple not equal to expected value",
186 "relation([str,str])", relationType);
187
188 RElem rElem_tupleValue = rTuple.getValue();
189 assertNotNull("Value of RTuple should not be null", rElem_tupleValue);
190
191 if (m_log.isDebugEnabled()) {
192 // debug found values
193 StringBuilder stringBuilder = new StringBuilder();
194 stringBuilder.append("\n\t" + "*RTuple name*\t= " + factName);
195 stringBuilder.append("\n\t" + "*RTuple type*\t= " + relationType);
196 stringBuilder.append("\n\t" + "*RTuple value*\t= "
197 + rElem_tupleValue);
198
199 m_log.debug("Found RStore values:\n" + stringBuilder.toString()
200 + "\n");
201 }
202 }
203
204 /**
205 * Creates a RStore and tries to register it.
206 *
207 * @author Ricardo Lindooren
208 * @author Arend van Beelen (reviewer)
209 * @date 2007-02-14
210 */
211 public void testRegisterRStore() throws Exception {
212
213 // destructive test, null input
214 RuntimeException runtimeException = null;
215 try {
216 m_container.registerRStore(null, null);
217 } catch (RuntimeException exception) {
218 runtimeException = exception;
219 }
220 assertNotNull("Should throw RuntimeException when File input is null",
221 runtimeException);
222
223 runtimeException = null;
224 try {
225 m_container.registerRStore(new File("bla"), null);
226 } catch (RuntimeException exception) {
227 runtimeException = exception;
228 }
229 assertNotNull(
230 "Should throw RuntimeException when RStore input is null",
231 runtimeException);
232
233 File testFile = getTestFile();
234 InputStream inputStream = m_container.inputStreamFromFile(testFile);
235 assertNotNull("Inputstream created from file should not be null",
236 inputStream);
237
238 RStore parsedRStore = m_container.parseRStore(inputStream);
239
240 // ---
241
242 // destructive test, insert first element with key-value 2 (by not using
243 // the registerRStore method)
244 m_container.getLoadedRStoreTrackersMap().put(new Integer(2),
245 new RStoreTracker(parsedRStore));
246 int idForRstoreAfterIllegalInsert = m_container.registerRStore(
247 testFile, parsedRStore);
248 assertEquals(3, idForRstoreAfterIllegalInsert);
249
250 // ---
251
252 m_container.getLoadedRStoreTrackersMap().clear();
253 m_container.getLoadedRStoreFilesMap().clear();
254
255 // ---
256
257 // Normal usage tests
258
259 int rStoreId = m_container.registerRStore(testFile, parsedRStore);
260 assertEquals("Id for RStore should be 1 after first time", 1, rStoreId);
261
262 // register same RStore file again
263
264 rStoreId = m_container.registerRStore(testFile, parsedRStore);
265 assertEquals("Id for RStore should be 1 after second time", 1, rStoreId);
266 assertEquals("Size of loadedRStoresMap should be 1", 1, m_container
267 .getLoadedRStoreTrackersMap().size());
268
269 // Register Updated RStore file (using the original filename but
270 // modified RStore data)
271 File updatedTestFile = getUpdatedTestFile();
272 RStore updatedRStore = m_container.parseRStore(new FileInputStream(updatedTestFile));
273
274 rStoreId = m_container.registerRStore(testFile, updatedRStore);
275 assertEquals("Id for RStore should be 1 after updating", 1, rStoreId);
276 assertEquals("Size of loadedRStoresMap should be 1", 1, m_container
277 .getLoadedRStoreTrackersMap().size());
278
279 // Register new RStore file (by faking a new filename)
280 rStoreId = m_container.registerRStore(new File("fakeFileName"), parsedRStore);
281 assertEquals("Id for RStore should be 2 after second time", 2, rStoreId);
282 assertEquals("Size of loadedRStoresMap should be 2", 2, m_container
283 .getLoadedRStoreTrackersMap().size());
284 }
285
286 /**
287 * Very simple test to make sure that the Map containing the loaded RStores
288 * is never null.
289 *
290 * @author Ricardo Lindooren
291 * @author Arend van Beelen (reviewer)
292 * @date 2007-02-14
293 */
294 public void testGetLoadedRStoresMap() {
295 assertNotNull("The loaded RStoresMap should never be null", m_container
296 .getLoadedRStoreTrackersMap());
297 }
298
299 /**
300 * Tests the rcLoadRstore method without having an actual connection with
301 * the Toolbus.
302 *
303 * Input and output is processed in this test.
304 *
305 * @author Ricardo Lindooren
306 * @author Arend van Beelen (reviewer)
307 * @date 2007-02-20
308 */
309 public void testRcLoadRstoreWithoutToolbusConnection() {
310
311 // destructive test with fake filename
312 final String fakeFileName = "testWithFakeFileName";
313 ATermApplImpl aTermApplImpl_response = (ATermApplImpl) m_container
314 .rcLoadRstore(fakeFileName);
315 ATermApplImpl aTermApplImpl_result = (ATermApplImpl) aTermApplImpl_response
316 .getArgument(0);
317
318 ATermApplImpl aTermApplImpl_fileName = (ATermApplImpl) aTermApplImpl_result
319 .getArgument(0);
320 ATermInt aTermInt_fileId = (ATermInt) aTermApplImpl_result
321 .getArgument(1);
322
323 assertEquals("Fake file name of RStore doesn't have expected value",
324 aTermApplImpl_fileName.getName(), fakeFileName);
325 assertEquals(
326 "File identifier of RStore doesn't have expected value after supplying fake file name",
327 aTermInt_fileId.getInt(), -1);
328
329 // normal use test with real filename
330 final String realFileName = getTestFile().toString();
331 ATermApplImpl aTermApplImpl_response2 = (ATermApplImpl) m_container
332 .rcLoadRstore(realFileName);
333 ATermApplImpl aTermApplImpl_result2 = (ATermApplImpl) aTermApplImpl_response2
334 .getArgument(0);
335
336 ATermApplImpl aTermApplImpl_fileName2 = (ATermApplImpl) aTermApplImpl_result2
337 .getArgument(0);
338 ATermInt aTermInt_fileId2 = (ATermInt) aTermApplImpl_result2
339 .getArgument(1);
340
341 assertEquals("File name of RStore doesn't have expected value",
342 aTermApplImpl_fileName2.getName(), realFileName);
343 assertEquals(
344 "FileIdentifier of RStore doesn't have expected value (it should be 1)",
345 1, aTermInt_fileId2.getInt());
346 }
347
348 /**
349 * Tests the rcGetRstoreFacts method without having an actual connection
350 * with the Toolbus.
351 *
352 * Input and output is processed in this test.
353 *
354 * @author Ricardo Lindooren
355 * @author Arend van Beelen (reviewer)
356 * @date 2007-02-20
357 */
358 public void testRcGetRstoreFactsWithoutToolbusConnection() {
359 // destructive test with non-existing rstore-id
360 ATermApplImpl aTermApplImpl_response = (ATermApplImpl) m_container
361 .rcGetRstoreFacts(1);
362 ATermApplImpl aTermList_result = (ATermApplImpl) aTermApplImpl_response
363 .getArgument(0);
364 ATermList aTermList_factInfos = (ATermList) aTermList_result
365 .getArgument(0);
366
367 assertEquals(
368 "RStore Facts Info list should be empty if retrieving facts for non-existing RStore ",
369 0, aTermList_factInfos.getLength());
370
371 // normal use test, registering a real Rstore file first
372 final String realFileName = getTestFile().toString();
373 m_container.rcLoadRstore(realFileName);
374
375 // get the facts for RStore with ID 1 (should exist)
376 ATermApplImpl aTermApplImpl_response2 = (ATermApplImpl) m_container
377 .rcGetRstoreFacts(1);
378 ATermApplImpl aTermList_result2 = (ATermApplImpl) aTermApplImpl_response2
379 .getArgument(0);
380 ATermList aTermList_factInfos2 = (ATermList) aTermList_result2
381 .getArgument(0);
382
383 assertEquals(
384 "RStore Facts Info list should contain one value (representing one fact) if retrieving facts for earlier registerd RStore",
385 1, aTermList_factInfos2.getLength());
386
387 ATermList atermList_factInfo = (ATermList) aTermList_factInfos2
388 .elementAt(0);
389
390 assertEquals(
391 "RStore Fact Info list should contain three values (representing id, name and type) if retrieving facts for earlier registerd RStore",
392 3, atermList_factInfo.getLength());
393 }
394
395 /**
396 * Tests the rcGetFactData method without having an actual connection with
397 * the Toolbus.
398 *
399 * Input and output is processed in this test.
400 *
401 * @author Ricardo Lindooren
402 * @author Arend van Beelen (reviewer + implemented assertions)
403 * @date 2007-02-20
404 */
405 public void testRcGetFactDataWithoutToolbusConnection() {
406
407 PureFactory pureFactory = RStoreContainer.getPureFactory();
408
409 // destructive test with fake RStore id and fake Fact id
410 ATerm expectedResult = pureFactory
411 .parse("snd-value(rc-fact-data(set([tuple([str(\"\"),str(\"\")])])))");
412 ATerm result = m_container.rcGetFactData(99, 3);
413 assertEquals("Result should be a fake empty set", expectedResult,
414 result);
415
416 // normal use test, registering a real Rstore file first
417 final String realFileName = getTestFile().toString();
418 m_container.rcLoadRstore(realFileName);
419
420 expectedResult = pureFactory
421 .parse("snd-value(rc-fact-data(rtuple(\"SIMPLE_GRAPH\",relation([str,str]),set([tuple([str(\"a\"),str(\"b\")]),tuple([str(\"b\"),str(\"c\")]),tuple([str(\"b\"),str(\"d\")]),tuple([str(\"c\"),str(\"d\")])]))))");
422 result = m_container.rcGetFactData(1, 1);
423 assertEquals("Result should match set from test file", expectedResult,
424 result);
425 }
426
427 /**
428 * Tests the rcUnloadRstore method without having an actual connection with
429 * the Toolbus.
430 *
431 * Input and output is processed in this test.
432 *
433 * @author Ricardo Lindooren
434 * @date 2007-03-14
435 */
436 public void testRcUnLoadRstoreWithoutToolbusConnection() {
437
438 // First destructive test (not exosting RStoreId)
439 ATermApplImpl aTermApplImpl_fakeUnloadResponse = (ATermApplImpl) m_container.rcUnloadRstore(999);
440 ATermApplImpl aTermApplImpl_fakeUnloadResponseResult = (ATermApplImpl) aTermApplImpl_fakeUnloadResponse.getArgument(0);
441 ATermInt aTermInt_fakeUnloadedId1 = (ATermInt) aTermApplImpl_fakeUnloadResponseResult.getArgument(0);
442 assertEquals("Returned value should be -1", -1, aTermInt_fakeUnloadedId1.getInt());
443
444 // Normal usage tests
445 final String realFileName = getTestFile().toString();
446 ATermApplImpl aTermApplImpl_response1 = (ATermApplImpl) m_container
447 .rcLoadRstore(realFileName);
448 ATermApplImpl aTermApplImpl_result1 = (ATermApplImpl) aTermApplImpl_response1
449 .getArgument(0);
450
451 ATermApplImpl aTermApplImpl_fileName1 = (ATermApplImpl) aTermApplImpl_result1
452 .getArgument(0);
453 ATermInt aTermInt_fileId1 = (ATermInt) aTermApplImpl_result1
454 .getArgument(1);
455
456 assertEquals("File name of RStore doesn't have expected value",
457 aTermApplImpl_fileName1.getName(), realFileName);
458 assertEquals(
459 "FileIdentifier of RStore doesn't have expected value (it should be 1)",
460 1, aTermInt_fileId1.getInt());
461
462 // Do the unloading
463 ATermApplImpl aTermApplImpl_unloadResponse = (ATermApplImpl) m_container.rcUnloadRstore(aTermInt_fileId1.getInt());
464 ATermApplImpl aTermApplImpl_unloadResponseResult = (ATermApplImpl) aTermApplImpl_unloadResponse.getArgument(0);
465 ATermInt aTermInt_unloadedId1 = (ATermInt) aTermApplImpl_unloadResponseResult.getArgument(0);
466
467 assertEquals("The ID of the unloaded RStore is not correct", aTermInt_fileId1.getInt(), aTermInt_unloadedId1.getInt());
468
469 assertEquals("The loaded RStoreFilesMap should be empty after unloading the only RStore", 0, m_container.getLoadedRStoreFilesMap().size());
470 assertEquals("The loaded RStoreTrackersMap should be empty after unloading the only RStore", 0, m_container.getLoadedRStoreTrackersMap().size());
471 }
472
473 /**
474 * Tests the constructor that is used to make a connection with the ToolBus.
475 *
476 * Because there is no Toolbus process available this test is used to test
477 * the try-catch blocks surrounding the connection initialization code.
478 *
479 * @author Ricardo Lindooren
480 * @author Arend van Beelen (reviewer)
481 * @date 2007-02-20
482 */
483 public void testToolbusConstructorWithoutToolbusConnection() {
484 String[] fakeArgs = { "" };
485 new RStoreContainer(fakeArgs);
486 }
487
488 /**
489 * Tests the static main method that is called by the ToolBus Java
490 * connector.
491 *
492 * Because there is no Toolbus process it will not really connect with the
493 * Toolbus.
494 *
495 * @author Ricardo Lindooren
496 * @author Arend van Beelen (reviewer)
497 * @date 2007-02-20
498 */
499 public void testMainWithoutToolbusConnection() {
500 String[] fakeArgs = { "fakeArg1", "fakeArg2" };
501 RStoreContainer.main(fakeArgs);
502
503 RStoreContainer.main(null);
504 }
505
506 /**
507 * Only calls the recTerminate method
508 *
509 * @author Ricardo Lindooren
510 * @author Arend van Beelen (reviewer)
511 * @date 2007-02-20
512 */
513 public void testRecTerminateWithoutToolbusConnection() {
514 m_container.recTerminate(null);
515 }
516
517 /**
518 * Very simple test to make sure that the Factory is never null
519 *
520 * @author Ricardo Lindooren
521 * @author Arend van Beelen (reviewer)
522 * @date 2007-02-14
523 */
524 public void testGetPureFactory() {
525 assertNotNull("The PureFactory should never be null", RStoreContainer.getPureFactory());
526 }
527
528 /**
529 * Returns a File reference to a test file.
530 *
531 * The test file is stored in the same package as this file.
532 *
533 * @return the test file
534 *
535 * @author Ricardo Lindooren
536 * @author Arend van Beelen (reviewer)
537 * @date 2007-02-13
538 */
539 private File getTestFile() {
540
541 StringBuilder stringBuilder = new StringBuilder();
542
543 Package packageOfThisClass = this.getClass().getPackage();
544
545 if (packageOfThisClass != null) {
546
547 String packageName = packageOfThisClass.getName();
548 if (packageName != null) {
549
550 packageName = packageName.replaceAll("\\.", "/");
551
552 stringBuilder.append("/");
553 stringBuilder.append(packageName);
554 stringBuilder.append("/");
555 }
556 }
557
558 stringBuilder.append(NAME_OF_TESTFILE);
559
560 URL url = this.getClass().getResource(stringBuilder.toString());
561
562 File testFile = null;
563 try {
564 testFile = new File(url.toURI());
565 } catch (URISyntaxException exception) {
566 exception.printStackTrace();
567 }
568
569 return testFile;
570 }
571
572 /**
573 * Returns a File reference to a test file that is a updated version of
574 * the default test file.
575 *
576 * The updated test file is stored in the same package as this file.
577 *
578 * @see #getTestFile()
579 *
580 * @return the updated test file
581 *
582 * @author Ricardo Lindooren
583 * @date 2007-03-13
584 */
585 private File getUpdatedTestFile() {
586
587 StringBuilder stringBuilder = new StringBuilder();
588
589 Package packageOfThisClass = this.getClass().getPackage();
590
591 if (packageOfThisClass != null) {
592
593 String packageName = packageOfThisClass.getName();
594 if (packageName != null) {
595
596 packageName = packageName.replaceAll("\\.", "/");
597
598 stringBuilder.append("/");
599 stringBuilder.append(packageName);
600 stringBuilder.append("/");
601 }
602 }
603
604 stringBuilder.append(NAME_OF_UPDATED_TESTFILE);
605
606 URL url = this.getClass().getResource(stringBuilder.toString());
607
608 File testFile = null;
609 try {
610 testFile = new File(url.toURI());
611 } catch (URISyntaxException exception) {
612 exception.printStackTrace();
613 }
614
615 return testFile;
616 }
617
618 /**
619 * Simple getter test
620 *
621 * @author Ricardo Lindooren
622 * @Date 2007-03-14
623 */
624 public void testGetName()
625 {
626 assertEquals("rStoreContainer",m_container.getName());
627 }
628
629 /**
630 * Only tests null input exceptions
631 *
632 * @author Ricardo Lindooren
633 * @Date 2007-03-14
634 */
635 public void testSendFactUpdatedEvents()
636 {
637 RuntimeException rex = null;
638 try{
639 m_container.sendFactUpdatedEvents(null, new ArrayList<Integer>());
640 }
641 catch(RuntimeException ex){
642 rex = ex;
643 }
644
645 assertNotNull(rex);
646
647 rex = null;
648
649 try{
650 m_container.sendFactUpdatedEvents(new Integer(1), null);
651 }
652 catch(RuntimeException ex){
653 rex = ex;
654 }
655
656 assertNotNull(rex);
657 }
658 }