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    }