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 }