Package de.nava.informa.utils.manager

Source Code of de.nava.informa.utils.manager.TestAbstractPersistenceManager$ExRunnable

//
// Informa -- RSS Library for Java
// Copyright (c) 2002 by Niko Schmuck
//
// Niko Schmuck
// http://sourceforge.net/projects/informa
// mailto:niko_schmuck@users.sourceforge.net
//
// This library is free software.
//
// You may redistribute it and/or modify it under the terms of the GNU
// Lesser General Public License as published by the Free Software Foundation.
//
// Version 2.1 of the license should be included with this distribution in
// the file LICENSE. If the license is not included with this distribution,
// you may find a copy at the FSF web site at 'www.gnu.org' or 'www.fsf.org',
// or you may write to the Free Software Foundation, 675 Mass Ave, Cambridge,
// MA 02139 USA.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied waranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// $Id: TestAbstractPersistenceManager.java,v 1.5 2006/12/04 23:43:26 italobb Exp $
//

package de.nava.informa.utils.manager;

import java.net.URL;
import java.util.Collection;

import junit.framework.TestCase;
import de.nava.informa.core.ChannelGroupIF;
import de.nava.informa.core.ChannelIF;
import de.nava.informa.core.ItemIF;

/**
* Test on persistence manager compatibility. This test is useful to make sure
* that your new persistence manager conforms to expectation. Let this test be
* your manager's first client.
*
* @author Aleksey Gureev (spyromus@noizeramp.com)
*/
public abstract class TestAbstractPersistenceManager extends TestCase {

  private static final int UID_STEP = 3;

  private PersistenceManagerIF manager;

  private static int testSeqNum = 0;

  /**
   * UID's are useful to get unique test names and different values.
   */
  private int tuid1, tuid2, tuid3;
  private String tuids1, tuids2, tuids3;
  private URL url1, url2, url3;

  protected void setUp() throws Exception {
    manager = getManager();

    // Create UID's for test
    tuid1 = testSeqNum += UID_STEP;
    tuid2 = tuid1 + 1;
    tuid3 = tuid2 + 1;

    // Create test String's
    tuids1 = Integer.toString(tuid1);
    tuids2 = Integer.toString(tuid2);
    tuids3 = Integer.toString(tuid3);

    // Create test URL's
    url1 = new URL("file:///test1");
    url2 = new URL("file:///test2");
    url3 = new URL("file:///test3");
  }

  /**
   * Returns manager to be tested.
   *
   * @return manager to be tested.
   */
  protected abstract PersistenceManagerIF getManager();

  // -----------------------------------------------------------------------------------------------
  // Groups
  // -----------------------------------------------------------------------------------------------

  /**
   * Simple test of group creation. Creates group and checks the filling of data fields.
   *
   * @see PersistenceManagerIF#createGroup
   */
  public void testCreateGroup() {
    ChannelGroupIF group = null;

    try {
      // Create simple group and check how the fields are filled
      group = manager.createGroup(tuids1);
      assertNotNull("Group object should be returned.", group);

      assertTrue("ID should be initialized with some meaningful value.", -1 != group.getId());
      assertEquals("Title should be set.", tuids1, group.getTitle());

      final ChannelGroupIF group2 = findGroupById(group.getId());
      assertTrue("Manager should operate with the same objects.", group == group2);
    } catch (PersistenceManagerException e)
    {
      e.printStackTrace();
      fail();
    } finally {
      // Delete the group
      try {
        if (group != null && group.getId() != -1) manager.deleteGroup(group);
      } catch (PersistenceManagerException e) {
        // We can do nothing here.
      }
    }
  }

  /**
   * Tests how group is deleted from storage.
   *
   * @see PersistenceManagerIF#deleteGroup
   */
  public void testDeleteGroup() {
    ChannelGroupIF group = null;

    try {
      // Create simple group
      group = manager.createGroup(tuids1);
      final long groupId = group.getId();
      manager.deleteGroup(group);

      assertEquals("Object ID should be turned back to -1.", -1, group.getId());
      final ChannelGroupIF group2 = findGroupById(groupId);
      assertNull("Object should be deleted from storage.", group2);
    } catch (PersistenceManagerException e) {
      e.printStackTrace();
      fail();
    }
  }

  /**
   * Tests how groups with assigned channels are deleted.
   *
   * @see PersistenceManagerIF#deleteGroup
   */
  public void testDeleteGroupCascade() {
    ChannelGroupIF group = null;
    ChannelIF channel = null;

    try {
      // Create simple group with channel
      group = manager.createGroup(tuids1);
      channel = manager.createChannel(tuids1, url1);
      manager.addChannelToGroup(channel, group);

      final long groupId = group.getId();
      manager.deleteGroup(group);

      assertEquals("Object ID should be turned back to -1.", -1, group.getId());
      final ChannelGroupIF group2 = findGroupById(groupId);
      assertNull("Object should be deleted from storage.", group2);
      assertEquals("Group still has channels assigned.", 0, group.getAll().size());
    } catch (PersistenceManagerException e) {
      e.printStackTrace();
      fail();
    } finally {
      try {
        if (channel != null && channel.getId() != -1) manager.deleteChannel(channel);
      } catch (PersistenceManagerException e) {
        // We can do nothing here
      }
    }
  }

  // -----------------------------------------------------------------------------------------------
  // Channels
  // -----------------------------------------------------------------------------------------------

  /**
   * Tests simple channel creation.
   *
   * @see PersistenceManagerIF#createChannel
   */
  public void testCreateChannel() {
    // Create channel and check
    ChannelIF channel = null;

    try {
      channel = manager.createChannel(tuids1, url1);
      assertNotNull("Channel object should be returned.", channel);
      assertTrue("ID should be initialized.", -1 != channel.getId());
      assertEquals("Title should be set.", tuids1, channel.getTitle());
    } catch (PersistenceManagerException e) {
      e.printStackTrace();
      fail();
    } finally {
      // Delete channel
      try {
        if (channel != null && channel.getId() != -1) manager.deleteChannel(channel);
      } catch (PersistenceManagerException e) {
        // We can do nothing here
      }
    }
  }

  /**
   * Checks simple channel deletion.
   *
   * @see PersistenceManagerIF#deleteChannel
   */
  public void testDeleteChannelSimple() {
    try {
      // Create channel
      final ChannelIF channel = manager.createChannel(tuids1, url1);

      // Delete channel
      manager.deleteChannel(channel);
      assertTrue("ID should be reset to uninitialized state (-1).", -1 == channel.getId());
    } catch (PersistenceManagerException e) {
      e.printStackTrace();
      fail();
    }
  }

  /**
   * Tests how channel is removed from group when it's deleted and how its items
   * are deleted as well.
   *
   * @see PersistenceManagerIF#deleteChannel
   */
  public void testDeleteChannelCascade() {
    ChannelGroupIF group = null;
    ChannelIF channel = null;
    ItemIF item1 = null;
    ItemIF item2 = null;

    try {
      // Create group and channel with two items
      group = manager.createGroup(tuids1);
      channel = manager.createChannel(tuids1, url1);
      item1 = manager.createItem(channel, tuids1);
      item2 = manager.createItem(channel, tuids2);

      // Put channel in group
      manager.addChannelToGroup(channel, group);

      // Delete channel
      manager.deleteChannel(channel);

      // Check that it was removed from parent group and all of its items gone too
      assertEquals("Group still has channels.", 0, group.getAll().size());
      assertEquals("Channel still has items.", 0, channel.getItems().size());
      assertEquals("Item still has initialized ID.", -1, item1.getId());
      assertEquals("Item still has initialized ID.", -1, item2.getId());
    } catch (PersistenceManagerException e) {
      e.printStackTrace();
      fail();
    } finally {
      // Delete channel, group and items
      try {
        if (item1 != null && item1.getId() != -1) manager.deleteItem(item1);
        if (item2 != null && item2.getId() != -1) manager.deleteItem(item2);
        if (channel != null && channel.getId() != -1) manager.deleteChannel(channel);
        if (group != null && group.getId() != -1) manager.deleteGroup(group);
      } catch (PersistenceManagerException e) {
        // We can do nothing here
      }
    }
  }

  /**
   * Tests how channels are added to groups.
   *
   * @see PersistenceManagerIF#addChannelToGroup
   */
  public void testAddChannelToGroup() {
    ChannelIF channel = null;
    ChannelGroupIF group = null;

    try {
      // Create channel & group
      channel = manager.createChannel(tuids1, url1);
      group = manager.createGroup(tuids2);

      // Add channel to group
      manager.addChannelToGroup(channel, group);
      final Collection channels = group.getAll();
      assertEquals("Channel isn't added to group.", 1, channels.size());
      assertEquals("Wrong channel was added to group.", channel, channels.iterator().next());

      // Add duplicate channel to group
      manager.addChannelToGroup(channel, group);
      final Collection channels2 = group.getAll();
      assertEquals("Duplicate channel shouldn't be added to group.", 1, channels2.size());
    } catch (PersistenceManagerException e) {
      e.printStackTrace();
      fail();
    } finally {
      // Delete channel and group
      try {
        if (channel != null && channel.getId() != -1) manager.deleteChannel(channel);
        if (group != null && group.getId() != -1) manager.deleteGroup(group);
      } catch (PersistenceManagerException e) {
        // We can do nothing here.
      }
    }
  }

  /**
   * Tests how channels are removed from group. Performs non-existing channel removing check.
   *
   * @see PersistenceManagerIF#removeChannelFromGroup
   */
  public void testRemoveChannelFromGroup() {
    ChannelIF channel = null;
    ChannelGroupIF group = null;

    try {
      // Create channel & group
      channel = manager.createChannel(tuids1, url1);
      group = manager.createGroup(tuids2);

      // Add channel to group
      manager.addChannelToGroup(channel, group);

      // Remove channel from group
      manager.removeChannelFromGroup(channel, group);
      final Collection channels = group.getAll();
      assertEquals("Channel wasn't removed from group.", 0, channels.size());

      // Remove not-existing channel from group
      manager.removeChannelFromGroup(channel, group);
      final Collection channels2 = group.getAll();
      assertEquals("Channel wasn't removed from group.", 0, channels2.size());
    } catch (PersistenceManagerException e) {
      e.printStackTrace();
      fail();
    } finally {
      // Delete channel and group
      try {
        if (channel != null) manager.deleteChannel(channel);
        if (group != null) manager.deleteGroup(group);
      } catch (PersistenceManagerException e) {
        // We can do nothing here.
      }
    }
  }

  /**
   * Tests how the groups are merged.
   *
   * @see PersistenceManagerIF#mergeGroups
   */
  public void testMergeChannels() {
    ChannelGroupIF group1 = null;
    ChannelGroupIF group2 = null;
    ChannelIF channel1 = null;
    ChannelIF channel2 = null;
    ChannelIF channel3 = null;

    try {
      // Create 2 grops and 3 channels: 1 in first group and 2 in the second
      group1 = manager.createGroup(tuids1);
      group2 = manager.createGroup(tuids2);
      channel1 = manager.createChannel(tuids1, url1);
      channel2 = manager.createChannel(tuids2, url2);
      channel3 = manager.createChannel(tuids3, url3);

      final long group2Id = group2.getId();

      // Add channels to groups
      manager.addChannelToGroup(channel1, group1);
      manager.addChannelToGroup(channel2, group2);
      manager.addChannelToGroup(channel3, group2);

      // Move channels from second to first
      manager.mergeGroups(group1, group2);

      // Check the lists of channels in groups
      final Collection channels1 = group1.getAll();
      assertNotNull(channels1);
      assertEquals("Channels are incorrectly moved to first group.", 3, channels1.size());
      assertTrue("Order of channels is incorrect.", channels1.contains(channel1));
      assertTrue("Order of channels is incorrect.", channels1.contains(channel2));
      assertTrue("Order of channels is incorrect.", channels1.contains(channel3));
      assertEquals("ID of removed group is still in intialized state.", -1, group2.getId());
      assertNull("Second group still can be found in storage.", findGroupById(group2Id));
    } catch (PersistenceManagerException e) {
      e.printStackTrace();
      fail();
    } finally {
      // Delete groups and channels
      try {
        if (group1 != null) manager.deleteGroup(group1);
        if (group2 != null && group2.getId() != -1) manager.deleteGroup(group2);
        if (channel1 != null) manager.deleteChannel(channel1);
        if (channel2 != null) manager.deleteChannel(channel2);
        if (channel3 != null) manager.deleteChannel(channel3);
      } catch (PersistenceManagerException e) {
        // We can do nothing here.
      }
    }
  }

  // -----------------------------------------------------------------------------------------------
  // Items
  // -----------------------------------------------------------------------------------------------

  /**
   * Checks simple item creation.
   *
   * @see PersistenceManagerIF#createItem
   */
  public void testCreateItem() {
    ChannelIF channel = null;
    ItemIF item = null;

    try {
      // Create channel and item
      channel = manager.createChannel(tuids1, url1);
      item = manager.createItem(channel, tuids2);

      // Check item
      assertNotNull(item);
      assertEquals("Title isn't properly initialized.", tuids2, item.getTitle());

      // Check channel
      final Collection items = channel.getItems();
      assertNotNull(items);
      assertEquals("Item was not correclty added to the channel.", 1, items.size());
      assertEquals("Incorrect item was added to the channel.", item, items.iterator().next());
    } catch (PersistenceManagerException e) {
      e.printStackTrace();
      fail();
    } finally {
      // Delete channel and item
      try {
        if (item != null) manager.deleteItem(item);
        if (channel != null) manager.deleteChannel(channel);
      } catch (PersistenceManagerException e) {
        // We can do nothing here.
      }
    }
  }

  /**
   * Checks creation of item using information from another item.
   *
   * @see PersistenceManagerIF#createItem
   */
  public void testCreateItemFromItem() {
    ChannelIF channel1 = null;
    ChannelIF channel2 = null;
    ItemIF item1 = null;
    ItemIF item2 = null;

    try {
      // Create two channels and item
      channel1 = manager.createChannel(tuids1, url1);
      channel2 = manager.createChannel(tuids2, url1);
      item1 = manager.createItem(channel1, tuids1);
      item2 = manager.createItem(channel2, item1);

      assertEquals("New item isn't matching its parent.", item1, item2);
    } catch (PersistenceManagerException e) {
      e.printStackTrace();
      fail();
    } finally {
      // Delete items and channels
      try {
        if (item1 != null) manager.deleteItem(item1);
        if (item2 != null) manager.deleteItem(item2);
        if (channel1 != null) manager.deleteChannel(channel1);
        if (channel2 != null) manager.deleteChannel(channel2);
      } catch (PersistenceManagerException e) {
        // We can do nothing here.
      }
    }
  }

  /**
   * Tests deletion of items.
   *
   * @see PersistenceManagerIF#deleteItem
   */
  public void testDeleteItem() {
    ChannelIF channel = null;
    ItemIF item1 = null;
    ItemIF item2 = null;

    try {
      // Create channel with two items
      channel = manager.createChannel(tuids1, url1);
      item1 = manager.createItem(channel, tuids1);
      item2 = manager.createItem(channel, tuids2);

      // Delete first item
      manager.deleteItem(item1);

      // Check item and channel
      assertEquals("Item ID should be in uninitialized state (-1).", -1, item1.getId());

      final Collection items = channel.getItems();
      assertNotNull(items);
      assertEquals("Number of items in list is incorrect.", 1, items.size());
      assertTrue("Wrong item was removed.", item2 == items.iterator().next());
    } catch (PersistenceManagerException e) {
      e.printStackTrace();
      fail();
    } finally {
      // Delete items and channel
      try {
        if (item1 != null && item1.getId() != -1) manager.deleteItem(item1);
        if (item2 != null && item2.getId() != -1) manager.deleteItem(item2);
        if (channel != null && channel.getId() != -1) manager.deleteChannel(channel);
      } catch (PersistenceManagerException e) {
        // We can do nothing here.
      }
    }
  }

  /**
   * Tests add,delete,add item sequence.
   */
  public void testAddDeleteAddItem() {
    ChannelIF channel = null;
    ItemIF item1 = null;
    ItemIF item2 = null;

    try {
      // Create channel with two items
      channel = manager.createChannel(tuids1, url1);
      item1 = manager.createItem(channel, tuids1);

      // Delete first item
      manager.deleteItem(item1);

      item2 = manager.createItem(channel, tuids2);

      // Check item and channel
      assertEquals("Item ID should be in uninitialized state (-1).", -1, item1.getId());

      final Collection items = channel.getItems();
      assertNotNull(items);
      assertEquals("Number of items in list is incorrect.", 1, items.size());
      assertTrue("Wrong item was removed.", item2 == items.iterator().next());
    } catch (PersistenceManagerException e) {
      fail();
    } finally {
      // Delete items and channel
      try {
        if (item1 != null && item1.getId() != -1) manager.deleteItem(item1);
        if (item2 != null && item2.getId() != -1) manager.deleteItem(item2);
        if (channel != null && channel.getId() != -1) manager.deleteChannel(channel);
      } catch (PersistenceManagerException e) {
        // We can do nothing here.
      }
    }
  }

  // -----------------------------------------------------------------------------------------------
  // Concurrency
  // -----------------------------------------------------------------------------------------------

  /**
   * Tests how concurent creation of items works.
   */
  public void testConcItemCreation()
  {
    final int itemsCount = 100;

    // Create empty channel
    ChannelIF chan = null;
    try {
      chan = manager.createChannel(tuids1, url1);
    } catch (PersistenceManagerException e) {
      e.printStackTrace();
      fail("Failed to create test channel.");
    }

    final ChannelIF channel = chan;

    // Create new thread which will be waiting for notification to start
    // creation of 10 items
    final RacingThread thread = new RacingThread(new ExRunnable() {

      /**
       * Runs the task and throws our any exceptions.
       *
       * @throws Exception in any case.
       */
      public void run() throws Exception {
        for (int i = 0; i < itemsCount; i++)
        {
          manager.createItem(channel, "i_tread_" + i);
        }
      }
    });

    // Start race
    boolean failed = false;
    thread.start();
    try {
      for (int i = 0; i < itemsCount; i++)
      {
        manager.createItem(channel, "i_" + i);
      }
    } catch (PersistenceManagerException e) {
      e.printStackTrace();
      failed = true;
    } finally {
      thread.waitForFinish();
    }

    // Check the results
    assertFalse("Main thread failed.", failed);
    if (thread.hasFailed()) {
      thread.getException().printStackTrace();
      fail("Racer thread failed.");
    }

    assertEquals("Incorrect number of items in channel.",
      itemsCount * 2, channel.getItems().size());
  }

  // -----------------------------------------------------------------------------------------------
  // Tools
  // -----------------------------------------------------------------------------------------------

  /**
   * Uses manager to get group by its ID.
   *
   * @param id  ID of group.
   *
   * @return group object or NULL if ID is not found.
   *
   * @throws PersistenceManagerException in cases of error.
   */
  private ChannelGroupIF findGroupById(long id)
    throws PersistenceManagerException {
    ChannelGroupIF result = null;

    final ChannelGroupIF[] groups = manager.getGroups();
    boolean found = false;
    int i = 0;
    while (i < groups.length && !found) {
      result = groups[i];
      found = result.getId() == id;
      i++;
    }

    return found ? result : null;
  }

  // -----------------------------------------------------------------------------------------------
  // Classes
  // -----------------------------------------------------------------------------------------------

  /**
   * Helper-thread to perform any concurrent tasks. Just give it Runnable task and start when
   * necessary. It will hold any exception from the task in internal variable, which is
   * accessible from outer world through <code>getException</code>.
   */
  private static class RacingThread extends Thread {

    private ExRunnable runnable;
    private Exception exception = null;
    private boolean finished;

    /**
     * Creates new single-race thread with task defined with Runnable.
     *
     * @param r task to execute.
     */
    public RacingThread(ExRunnable r) {
      runnable = r;
    }

    /**
     * Waits for the 'green light' from <code>startRace</code> and does the task.
     */
    public void run() {
      finished = false;
      // Do the job
      try {
        runnable.run();
      } catch (Exception e) {
        exception = e;
      }

      // notify about finish
      synchronized (this) {
        finished = true;
        this.notify();
      }
    }

    /**
     * Returns TRUE if thread failed to do the job. Exception is availble through
     * <code>getException()</code>.
     *
     * @return TRUE if failed to finish.
     */
    public boolean hasFailed() {
      return exception != null;
    }

    /**
     * Returns Exception from the task if any.
     *
     * @return Exception or NULL.
     */
    public Exception getException() {
      return exception;
    }

    /**
     * Waits for thread to finish.
     */
    public void waitForFinish()
    {
      synchronized(this) {
        if (!finished) {
          try {
            wait();
          } catch (InterruptedException e) {
          }
        }
      }
    }
  }

  /**
   * Runnable task, which is capable to throw exceptions out.
   */
  private static interface ExRunnable {
    /**
     * Runs the task and throws our any exceptions.
     *
     * @throws Exception in any case.
     */
    public void run() throws Exception;
  }
}
TOP

Related Classes of de.nava.informa.utils.manager.TestAbstractPersistenceManager$ExRunnable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.