KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > nava > informa > utils > manager > TestAbstractPersistenceManager


1 //
2
// Informa -- RSS Library for Java
3
// Copyright (c) 2002 by Niko Schmuck
4
//
5
// Niko Schmuck
6
// http://sourceforge.net/projects/informa
7
// mailto:niko_schmuck@users.sourceforge.net
8
//
9
// This library is free software.
10
//
11
// You may redistribute it and/or modify it under the terms of the GNU
12
// Lesser General Public License as published by the Free Software Foundation.
13
//
14
// Version 2.1 of the license should be included with this distribution in
15
// the file LICENSE. If the license is not included with this distribution,
16
// you may find a copy at the FSF web site at 'www.gnu.org' or 'www.fsf.org',
17
// or you may write to the Free Software Foundation, 675 Mass Ave, Cambridge,
18
// MA 02139 USA.
19
//
20
// This library is distributed in the hope that it will be useful,
21
// but WITHOUT ANY WARRANTY; without even the implied waranty of
22
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23
// Lesser General Public License for more details.
24
//
25
// $Id: TestAbstractPersistenceManager.java,v 1.2 2004/09/02 09:19:16 spyromus Exp $
26
//
27

28 package de.nava.informa.utils.manager;
29
30 import de.nava.informa.core.ChannelGroupIF;
31 import de.nava.informa.core.ChannelIF;
32 import de.nava.informa.core.ItemIF;
33 import junit.framework.TestCase;
34
35 import java.net.URL JavaDoc;
36 import java.util.Collection JavaDoc;
37
38 /**
39  * Test on persistence manager compatibility. This test is useful to make sure
40  * that your new persistence manager conforms to expectation. Let this test be
41  * your manager's first client.
42  *
43  * @author Aleksey Gureev (spyromus@noizeramp.com)
44  */

45 public abstract class TestAbstractPersistenceManager extends TestCase {
46
47   private static final int UID_STEP = 3;
48
49   private PersistenceManagerIF manager;
50
51   private static int testSeqNum = 0;
52
53   /**
54    * UID's are useful to get unique test names and different values.
55    */

56   private int tuid1, tuid2, tuid3;
57   private String JavaDoc tuids1, tuids2, tuids3;
58   private URL JavaDoc url1, url2, url3;
59
60   protected void setUp() throws Exception JavaDoc {
61     manager = getManager();
62
63     // Create UID's for test
64
tuid1 = testSeqNum += UID_STEP;
65     tuid2 = tuid1 + 1;
66     tuid3 = tuid2 + 1;
67
68     // Create test String's
69
tuids1 = Integer.toString(tuid1);
70     tuids2 = Integer.toString(tuid2);
71     tuids3 = Integer.toString(tuid3);
72
73     // Create test URL's
74
url1 = new URL JavaDoc("file:///test1");
75     url2 = new URL JavaDoc("file:///test2");
76     url3 = new URL JavaDoc("file:///test3");
77   }
78
79   /**
80    * Returns manager to be tested.
81    *
82    * @return manager to be tested.
83    */

84   protected abstract PersistenceManagerIF getManager();
85
86   // -----------------------------------------------------------------------------------------------
87
// Groups
88
// -----------------------------------------------------------------------------------------------
89

90   /**
91    * Simple test of group creation. Creates group and checks the filling of data fields.
92    *
93    * @see PersistenceManagerIF#createGroup
94    */

95   public void testCreateGroup() {
96     ChannelGroupIF group = null;
97
98     try {
99       // Create simple group and check how the fields are filled
100
group = manager.createGroup(tuids1);
101       assertNotNull("Group object should be returned.", group);
102
103       assertTrue("ID should be initialized with some meaningful value.", -1 != group.getId());
104       assertEquals("Title should be set.", tuids1, group.getTitle());
105
106       final ChannelGroupIF group2 = findGroupById(group.getId());
107       assertTrue("Manager should operate with the same objects.", group == group2);
108     } catch (PersistenceManagerException e)
109     {
110       e.printStackTrace();
111       fail();
112     } finally {
113       // Delete the group
114
try {
115         if (group != null && group.getId() != -1) manager.deleteGroup(group);
116       } catch (PersistenceManagerException e) {
117         // We can do nothing here.
118
}
119     }
120   }
121
122   /**
123    * Tests how group is deleted from storage.
124    *
125    * @see PersistenceManagerIF#deleteGroup
126    */

127   public void testDeleteGroup() {
128     ChannelGroupIF group = null;
129
130     try {
131       // Create simple group
132
group = manager.createGroup(tuids1);
133       final long groupId = group.getId();
134       manager.deleteGroup(group);
135
136       assertEquals("Object ID should be turned back to -1.", -1, group.getId());
137       final ChannelGroupIF group2 = findGroupById(groupId);
138       assertNull("Object should be deleted from storage.", group2);
139     } catch (PersistenceManagerException e) {
140       e.printStackTrace();
141       fail();
142     }
143   }
144
145   /**
146    * Tests how groups with assigned channels are deleted.
147    *
148    * @see PersistenceManagerIF#deleteGroup
149    */

150   public void testDeleteGroupCascade() {
151     ChannelGroupIF group = null;
152     ChannelIF channel = null;
153
154     try {
155       // Create simple group with channel
156
group = manager.createGroup(tuids1);
157       channel = manager.createChannel(tuids1, url1);
158       manager.addChannelToGroup(channel, group);
159
160       final long groupId = group.getId();
161       manager.deleteGroup(group);
162
163       assertEquals("Object ID should be turned back to -1.", -1, group.getId());
164       final ChannelGroupIF group2 = findGroupById(groupId);
165       assertNull("Object should be deleted from storage.", group2);
166       assertEquals("Group still has channels assigned.", 0, group.getAll().size());
167     } catch (PersistenceManagerException e) {
168       e.printStackTrace();
169       fail();
170     } finally {
171       try {
172         if (channel != null && channel.getId() != -1) manager.deleteChannel(channel);
173       } catch (PersistenceManagerException e) {
174         // We can do nothing here
175
}
176     }
177   }
178
179   // -----------------------------------------------------------------------------------------------
180
// Channels
181
// -----------------------------------------------------------------------------------------------
182

183   /**
184    * Tests simple channel creation.
185    *
186    * @see PersistenceManagerIF#createChannel
187    */

188   public void testCreateChannel() {
189     // Create channel and check
190
ChannelIF channel = null;
191
192     try {
193       channel = manager.createChannel(tuids1, url1);
194       assertNotNull("Channel object should be returned.", channel);
195       assertTrue("ID should be initialized.", -1 != channel.getId());
196       assertEquals("Title should be set.", tuids1, channel.getTitle());
197     } catch (PersistenceManagerException e) {
198       e.printStackTrace();
199       fail();
200     } finally {
201       // Delete channel
202
try {
203         if (channel != null && channel.getId() != -1) manager.deleteChannel(channel);
204       } catch (PersistenceManagerException e) {
205         // We can do nothing here
206
}
207     }
208   }
209
210   /**
211    * Checks simple channel deletion.
212    *
213    * @see PersistenceManagerIF#deleteChannel
214    */

215   public void testDeleteChannelSimple() {
216     try {
217       // Create channel
218
final ChannelIF channel = manager.createChannel(tuids1, url1);
219
220       // Delete channel
221
manager.deleteChannel(channel);
222       assertTrue("ID should be reset to uninitialized state (-1).", -1 == channel.getId());
223     } catch (PersistenceManagerException e) {
224       e.printStackTrace();
225       fail();
226     }
227   }
228
229   /**
230    * Tests how channel is removed from group when it's deleted and how its items
231    * are deleted as well.
232    *
233    * @see PersistenceManagerIF#deleteChannel
234    */

235   public void testDeleteChannelCascade() {
236     ChannelGroupIF group = null;
237     ChannelIF channel = null;
238     ItemIF item1 = null;
239     ItemIF item2 = null;
240
241     try {
242       // Create group and channel with two items
243
group = manager.createGroup(tuids1);
244       channel = manager.createChannel(tuids1, url1);
245       item1 = manager.createItem(channel, tuids1);
246       item2 = manager.createItem(channel, tuids2);
247
248       // Put channel in group
249
manager.addChannelToGroup(channel, group);
250
251       // Delete channel
252
manager.deleteChannel(channel);
253
254       // Check that it was removed from parent group and all of its items gone too
255
assertEquals("Group still has channels.", 0, group.getAll().size());
256       assertEquals("Channel still has items.", 0, channel.getItems().size());
257       assertEquals("Item still has initialized ID.", -1, item1.getId());
258       assertEquals("Item still has initialized ID.", -1, item2.getId());
259     } catch (PersistenceManagerException e) {
260       e.printStackTrace();
261       fail();
262     } finally {
263       // Delete channel, group and items
264
try {
265         if (item1 != null && item1.getId() != -1) manager.deleteItem(item1);
266         if (item2 != null && item2.getId() != -1) manager.deleteItem(item2);
267         if (channel != null && channel.getId() != -1) manager.deleteChannel(channel);
268         if (group != null && group.getId() != -1) manager.deleteGroup(group);
269       } catch (PersistenceManagerException e) {
270         // We can do nothing here
271
}
272     }
273   }
274
275   /**
276    * Tests how channels are added to groups.
277    *
278    * @see PersistenceManagerIF#addChannelToGroup
279    */

280   public void testAddChannelToGroup() {
281     ChannelIF channel = null;
282     ChannelGroupIF group = null;
283
284     try {
285       // Create channel & group
286
channel = manager.createChannel(tuids1, url1);
287       group = manager.createGroup(tuids2);
288
289       // Add channel to group
290
manager.addChannelToGroup(channel, group);
291       final Collection JavaDoc channels = group.getAll();
292       assertEquals("Channel isn't added to group.", 1, channels.size());
293       assertEquals("Wrong channel was added to group.", channel, channels.iterator().next());
294
295       // Add duplicate channel to group
296
manager.addChannelToGroup(channel, group);
297       final Collection JavaDoc channels2 = group.getAll();
298       assertEquals("Duplicate channel shouldn't be added to group.", 1, channels2.size());
299     } catch (PersistenceManagerException e) {
300       e.printStackTrace();
301       fail();
302     } finally {
303       // Delete channel and group
304
try {
305         if (channel != null && channel.getId() != -1) manager.deleteChannel(channel);
306         if (group != null && group.getId() != -1) manager.deleteGroup(group);
307       } catch (PersistenceManagerException e) {
308         // We can do nothing here.
309
}
310     }
311   }
312
313   /**
314    * Tests how channels are removed from group. Performs non-existing channel removing check.
315    *
316    * @see PersistenceManagerIF#removeChannelFromGroup
317    */

318   public void testRemoveChannelFromGroup() {
319     ChannelIF channel = null;
320     ChannelGroupIF group = null;
321
322     try {
323       // Create channel & group
324
channel = manager.createChannel(tuids1, url1);
325       group = manager.createGroup(tuids2);
326
327       // Add channel to group
328
manager.addChannelToGroup(channel, group);
329
330       // Remove channel from group
331
manager.removeChannelFromGroup(channel, group);
332       final Collection JavaDoc channels = group.getAll();
333       assertEquals("Channel wasn't removed from group.", 0, channels.size());
334
335       // Remove not-existing channel from group
336
manager.removeChannelFromGroup(channel, group);
337       final Collection JavaDoc channels2 = group.getAll();
338       assertEquals("Channel wasn't removed from group.", 0, channels2.size());
339     } catch (PersistenceManagerException e) {
340       e.printStackTrace();
341       fail();
342     } finally {
343       // Delete channel and group
344
try {
345         if (channel != null) manager.deleteChannel(channel);
346         if (group != null) manager.deleteGroup(group);
347       } catch (PersistenceManagerException e) {
348         // We can do nothing here.
349
}
350     }
351   }
352
353   /**
354    * Tests how the groups are merged.
355    *
356    * @see PersistenceManagerIF#mergeGroups
357    */

358   public void testMergeChannels() {
359     ChannelGroupIF group1 = null;
360     ChannelGroupIF group2 = null;
361     ChannelIF channel1 = null;
362     ChannelIF channel2 = null;
363     ChannelIF channel3 = null;
364
365     try {
366       // Create 2 grops and 3 channels: 1 in first group and 2 in the second
367
group1 = manager.createGroup(tuids1);
368       group2 = manager.createGroup(tuids2);
369       channel1 = manager.createChannel(tuids1, url1);
370       channel2 = manager.createChannel(tuids2, url2);
371       channel3 = manager.createChannel(tuids3, url3);
372
373       final long group2Id = group2.getId();
374
375       // Add channels to groups
376
manager.addChannelToGroup(channel1, group1);
377       manager.addChannelToGroup(channel2, group2);
378       manager.addChannelToGroup(channel3, group2);
379
380       // Move channels from second to first
381
manager.mergeGroups(group1, group2);
382
383       // Check the lists of channels in groups
384
final Collection JavaDoc channels1 = group1.getAll();
385       assertNotNull(channels1);
386       assertEquals("Channels are incorrectly moved to first group.", 3, channels1.size());
387       assertTrue("Order of channels is incorrect.", channels1.contains(channel1));
388       assertTrue("Order of channels is incorrect.", channels1.contains(channel2));
389       assertTrue("Order of channels is incorrect.", channels1.contains(channel3));
390       assertEquals("ID of removed group is still in intialized state.", -1, group2.getId());
391       assertNull("Second group still can be found in storage.", findGroupById(group2Id));
392     } catch (PersistenceManagerException e) {
393       e.printStackTrace();
394       fail();
395     } finally {
396       // Delete groups and channels
397
try {
398         if (group1 != null) manager.deleteGroup(group1);
399         if (group2 != null && group2.getId() != -1) manager.deleteGroup(group2);
400         if (channel1 != null) manager.deleteChannel(channel1);
401         if (channel2 != null) manager.deleteChannel(channel2);
402         if (channel3 != null) manager.deleteChannel(channel3);
403       } catch (PersistenceManagerException e) {
404         // We can do nothing here.
405
}
406     }
407   }
408
409   // -----------------------------------------------------------------------------------------------
410
// Items
411
// -----------------------------------------------------------------------------------------------
412

413   /**
414    * Checks simple item creation.
415    *
416    * @see PersistenceManagerIF#createItem
417    */

418   public void testCreateItem() {
419     ChannelIF channel = null;
420     ItemIF item = null;
421
422     try {
423       // Create channel and item
424
channel = manager.createChannel(tuids1, url1);
425       item = manager.createItem(channel, tuids2);
426
427       // Check item
428
assertNotNull(item);
429       assertEquals("Title isn't properly initialized.", tuids2, item.getTitle());
430
431       // Check channel
432
final Collection JavaDoc items = channel.getItems();
433       assertNotNull(items);
434       assertEquals("Item was not correclty added to the channel.", 1, items.size());
435       assertEquals("Incorrect item was added to the channel.", item, items.iterator().next());
436     } catch (PersistenceManagerException e) {
437       e.printStackTrace();
438       fail();
439     } finally {
440       // Delete channel and item
441
try {
442         if (item != null) manager.deleteItem(item);
443         if (channel != null) manager.deleteChannel(channel);
444       } catch (PersistenceManagerException e) {
445         // We can do nothing here.
446
}
447     }
448   }
449
450   /**
451    * Checks creation of item using information from another item.
452    *
453    * @see PersistenceManagerIF#createItem
454    */

455   public void testCreateItemFromItem() {
456     ChannelIF channel1 = null;
457     ChannelIF channel2 = null;
458     ItemIF item1 = null;
459     ItemIF item2 = null;
460
461     try {
462       // Create two channels and item
463
channel1 = manager.createChannel(tuids1, url1);
464       channel2 = manager.createChannel(tuids2, url1);
465       item1 = manager.createItem(channel1, tuids1);
466       item2 = manager.createItem(channel2, item1);
467
468       assertEquals("New item isn't matching its parent.", item1, item2);
469     } catch (PersistenceManagerException e) {
470       e.printStackTrace();
471       fail();
472     } finally {
473       // Delete items and channels
474
try {
475         if (item1 != null) manager.deleteItem(item1);
476         if (item2 != null) manager.deleteItem(item2);
477         if (channel1 != null) manager.deleteChannel(channel1);
478         if (channel2 != null) manager.deleteChannel(channel2);
479       } catch (PersistenceManagerException e) {
480         // We can do nothing here.
481
}
482     }
483   }
484
485   /**
486    * Tests deletion of items.
487    *
488    * @see PersistenceManagerIF#deleteItem
489    */

490   public void testDeleteItem() {
491     ChannelIF channel = null;
492     ItemIF item1 = null;
493     ItemIF item2 = null;
494
495     try {
496       // Create channel with two items
497
channel = manager.createChannel(tuids1, url1);
498       item1 = manager.createItem(channel, tuids1);
499       item2 = manager.createItem(channel, tuids2);
500
501       // Delete first item
502
manager.deleteItem(item1);
503
504       // Check item and channel
505
assertEquals("Item ID should be in uninitialized state (-1).", -1, item1.getId());
506
507       final Collection JavaDoc items = channel.getItems();
508       assertNotNull(items);
509       assertEquals("Number of items in list is incorrect.", 1, items.size());
510       assertTrue("Wrong item was removed.", item2 == items.iterator().next());
511     } catch (PersistenceManagerException e) {
512       e.printStackTrace();
513       fail();
514     } finally {
515       // Delete items and channel
516
try {
517         if (item1 != null && item1.getId() != -1) manager.deleteItem(item1);
518         if (item2 != null && item2.getId() != -1) manager.deleteItem(item2);
519         if (channel != null && channel.getId() != -1) manager.deleteChannel(channel);
520       } catch (PersistenceManagerException e) {
521         // We can do nothing here.
522
}
523     }
524   }
525
526   // -----------------------------------------------------------------------------------------------
527
// Concurrency
528
// -----------------------------------------------------------------------------------------------
529

530   /**
531    * Tests how concurent creation of items works.
532    */

533   public void testConcItemCreation()
534   {
535     final int itemsCount = 100;
536
537     // Create empty channel
538
ChannelIF chan = null;
539     try {
540       chan = manager.createChannel(tuids1, url1);
541     } catch (PersistenceManagerException e) {
542       e.printStackTrace();
543       fail("Failed to create test channel.");
544     }
545
546     final ChannelIF channel = chan;
547
548     // Create new thread which will be waiting for notification to start
549
// creation of 10 items
550
final RacingThread thread = new RacingThread(new ExRunnable() {
551
552       /**
553        * Runs the task and throws our any exceptions.
554        *
555        * @throws Exception in any case.
556        */

557       public void run() throws Exception JavaDoc {
558         for (int i = 0; i < itemsCount; i++)
559         {
560           manager.createItem(channel, "i_tread_" + i);
561         }
562       }
563     });
564
565     // Start race
566
boolean failed = false;
567     thread.start();
568     try {
569       for (int i = 0; i < itemsCount; i++)
570       {
571         manager.createItem(channel, "i_" + i);
572       }
573     } catch (PersistenceManagerException e) {
574       e.printStackTrace();
575       failed = true;
576     } finally {
577       thread.waitForFinish();
578     }
579
580     // Check the results
581
assertFalse("Main thread failed.", failed);
582     if (thread.hasFailed()) {
583       thread.getException().printStackTrace();
584       fail("Racer thread failed.");
585     }
586
587     assertEquals("Incorrect number of items in channel.",
588       itemsCount * 2, channel.getItems().size());
589   }
590
591   // -----------------------------------------------------------------------------------------------
592
// Tools
593
// -----------------------------------------------------------------------------------------------
594

595   /**
596    * Uses manager to get group by its ID.
597    *
598    * @param id ID of group.
599    *
600    * @return group object or NULL if ID is not found.
601    *
602    * @throws PersistenceManagerException in cases of error.
603    */

604   private ChannelGroupIF findGroupById(long id)
605     throws PersistenceManagerException {
606     ChannelGroupIF result = null;
607
608     final ChannelGroupIF[] groups = manager.getGroups();
609     boolean found = false;
610     int i = 0;
611     while (i < groups.length && !found) {
612       result = groups[i];
613       found = result.getId() == id;
614       i++;
615     }
616
617     return found ? result : null;
618   }
619
620   // -----------------------------------------------------------------------------------------------
621
// Classes
622
// -----------------------------------------------------------------------------------------------
623

624   /**
625    * Helper-thread to perform any concurrent tasks. Just give it Runnable task and start when
626    * necessary. It will hold any exception from the task in internal variable, which is
627    * accessible from outer world through <code>getException</code>.
628    */

629   private static class RacingThread extends Thread JavaDoc {
630
631     private ExRunnable runnable;
632     private Exception JavaDoc exception;
633     private boolean finished;
634
635     /**
636      * Creates new single-race thread with task defined with Runnable.
637      *
638      * @param r task to execute.
639      */

640     public RacingThread(ExRunnable r) {
641       runnable = r;
642     }
643
644     /**
645      * Waits for the 'green light' from <code>startRace</code> and does the task.
646      */

647     public void run() {
648       finished = false;
649       // Do the job
650
try {
651         runnable.run();
652       } catch (Exception JavaDoc e) {
653         exception = e;
654       }
655
656       // notify about finish
657
synchronized (this) {
658         finished = true;
659         this.notify();
660       }
661     }
662
663     /**
664      * Returns TRUE if thread failed to do the job. Exception is availble through
665      * <code>getException()</code>.
666      *
667      * @return TRUE if failed to finish.
668      */

669     public boolean hasFailed() {
670       return exception != null;
671     }
672
673     /**
674      * Returns Exception from the task if any.
675      *
676      * @return Exception or NULL.
677      */

678     public Exception JavaDoc getException() {
679       return exception;
680     }
681
682     /**
683      * Waits for thread to finish.
684      */

685     public void waitForFinish()
686     {
687       synchronized(this) {
688         if (!finished) {
689           try {
690             wait();
691           } catch (InterruptedException JavaDoc e) {
692           }
693         }
694       }
695     }
696   }
697
698   /**
699    * Runnable task, which is capable to throw exceptions out.
700    */

701   private static interface ExRunnable {
702     /**
703      * Runs the task and throws our any exceptions.
704      *
705      * @throws Exception in any case.
706      */

707     public void run() throws Exception JavaDoc;
708   }
709 }
710
Popular Tags