Package com.sun.jini.test.spec.renewalservice

Source Code of com.sun.jini.test.spec.renewalservice.EventSequenceFailTest

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.sun.jini.test.spec.renewalservice;

import java.util.logging.Level;

// java.io
import java.io.IOException;

// java.util
import java.util.Iterator;
import java.util.TreeSet;

// net.jini
import net.jini.core.event.RemoteEvent;
import net.jini.core.lease.Lease;
import net.jini.lease.LeaseRenewalService;
import net.jini.lease.LeaseRenewalSet;
import net.jini.lease.RenewalFailureEvent;

//
import com.sun.jini.qa.harness.TestException;

// com.sun.jini.qa
import com.sun.jini.qa.harness.QATest;
import com.sun.jini.test.share.RenewingRemoteListener;
import com.sun.jini.test.share.TestLease;
import com.sun.jini.test.share.TestLeaseProvider;
import com.sun.jini.test.share.FailingOpCountingOwner;

/**
* Assert that the events of the RenewalFailureEvent type sent to a
* newly registered listener are in the same sequence as those sent to
* the previously registered listener. 
*
* <P>Note:<BR>This test is stronger than the EventSequenceWarnTest
* because the RenewalFailureEvent carries a reference to the lease
* whose renewal failed and thus imparts to the event an identity thay
* cana be used to distinguish between two different events thay might
* have the same sequence number).</P>
*
*/
public class EventSequenceFailTest extends AbstractLeaseRenewalServiceTest {
   
    /**
     * The maximum time granted for a lease by a renew operation.
     */
    private long renewGrant = 0;

    /**
     * The default value renewGrant
     */
    private final long DEFAULT_RENEW_GRANT = 30 * 1000; // 30 seconds

    /**
     * Provides leases for this test.
     */
    private TestLeaseProvider earlyLeaseProvider = null;
    private TestLeaseProvider lateLeaseProvider = null;

    /**
     * Listeners of the RenewalFailureEvents
     */
    private RenewingRemoteListener rrl01 = null;
    private RenewingRemoteListener rrl02 = null;

    /**
     * Owner (aka Landlord) of the leases
     */
    FailingOpCountingOwner owner = null;

    /**
     * Sets up the testing environment.
     */
    public void setup(com.sun.jini.qa.harness.QAConfig sysConfig) throws Exception {

       // mandatory call to parent
       super.setup(sysConfig);
 
       // Announce where we are in the test
       logger.log(Level.FINE, "EventSequenceFailTest: In setup() method.");

       // object from which test leases are obtained
       earlyLeaseProvider = new TestLeaseProvider(4);
       lateLeaseProvider = new TestLeaseProvider(4);

       // capture the renewal time
       String property = "com.sun.jini.test.spec.renewalservice.renewGrant";
       renewGrant = getConfig().getLongConfigVal(property, DEFAULT_RENEW_GRANT);

       // create an owner for the lease that will throw a definite exception
       // create an owner to for testing definite exceptions
       Exception ex = new IllegalArgumentException("EventSequenceFailTest");
       owner = new FailingOpCountingOwner(ex, 0, renewGrant);

       // logs events as they arrive
       rrl01 = new RenewingRemoteListener(getExporter(), renewGrant);
       rrl02 = new RenewingRemoteListener(getExporter(), renewGrant);
    }


    /**
     * Assert that the events of the RenewalFailureEvent type sent to a
     * newly registered listener are in the same sequence as those sent to
     * the previously registered listener.
     */
    public void run() throws Exception {

  // Announce where we are in the test
  logger.log(Level.FINE, "EventSequenceFailTest: In run() method.");

  // get a lease renewal set w/ duration for as long as we can
  logger.log(Level.FINE, "Creating the lease renewal set with duration" +
        " of Lease.FOREVER");
  LeaseRenewalService lrs = getLRS();
  LeaseRenewalSet set = lrs.createLeaseRenewalSet(Lease.FOREVER);
  set = prepareSet(set);
 
  // register listener #1 to receive events
  logger.log(Level.FINE, "Registering listener #1 for renewal failure" +
        " events.");
  set.setRenewalFailureListener(rrl01, null);

  /* create 8 test leases which will throw definite exceptions
     and add then to the renewal set. Each lease's expriation
     time is 30 seconds greater than the previous one. */
  long duration = 0;
  TestLease[] lease = new TestLease[8];
      TestLeaseProvider leaseProvider = null;
  for (int i = 0; i < 8; ++i) {
      duration = renewGrant * (i+1);
      logger.log(Level.FINE, "Creating lease #" + i +
            " with duration of " + duration +
            " milliseconds.");
      leaseProvider = (i < 4) ? earlyLeaseProvider :
              lateLeaseProvider;
      lease[i] =
    leaseProvider.createNewLease(owner,
               rstUtil.durToExp(duration));
      logger.log(Level.FINE, "Adding lease #" + i + " to renewal set " +
            "with membership duration = Lease.FOREVER.");
      set.renewFor(lease[i], Lease.FOREVER);
  }

  // wait for the listener to receive four events.
  long timeOut = duration;
  rstUtil.waitForRemoteEvents(rrl01, 4, timeOut);

  // assign the other listener to receive events
  logger.log(Level.FINE, "Replacing listener #1 with listener #2 to" +
        " receive renewal failure events.");
  set.setRenewalFailureListener(rrl02, null);

  // wait for the other listener to receive four events.
  rstUtil.waitForRemoteEvents(rrl02, 4, timeOut);

  // report on how many events were received by each (must be >= 3)
  RemoteEvent[] events01 = rrl01.getEvents();
  RemoteEvent[] events02 = rrl02.getEvents();

  if (events01.length < 4) {
      String message = "Listener #1 received " + events01.length +
    " events but is required to receive exactly 4.";
      throw new TestException(message);
  }
  logger.log(Level.FINE, "Listener #1 received " + events01.length +
        " RenewalFailureEvents.");

  if (events02.length < 4) {
      String message = "Listener #2 received " + events02.length +
    " events but is required to receive exactly 4.";
      throw new TestException(message);
  }
  logger.log(Level.FINE, "Listener #2 received " + events02.length +
        " RenewalFailureEvents.");

  /* create a sorted collection of each of the event sets.
     the assumption here is that the events need not arrive
     in order, but we are assuming a reliable network so they
     all must arrive. */
  TreeSet sequenceSet01 = new TreeSet();
  TreeSet sequenceSet02 = new TreeSet();

  for (int i = 0; i < events01.length; ++i) {
      sequenceSet01.add(new Long(events01[i].getSequenceNumber()));
  }

  for (int i = 0; i < events02.length; ++i) {
      sequenceSet02.add(new Long(events02[i].getSequenceNumber()));
  }

  // assert that each sequence is in order with no gaps

  // first sequenceSet01
  Iterator iter = sequenceSet01.iterator();
  Long previousLong = (Long) iter.next();
  while (iter.hasNext()) {
      Long nextLong = (Long) iter.next();
      logger.log(Level.FINE, "previousID = " + previousLong +
            " nextID = " + nextLong);
      long delta = nextLong.longValue() - previousLong.longValue();
      if (delta != 1) {
    String message = "Event sequence numbers are not" +
        " strictly increasing for listener #1.";
    throw new TestException(message);
      }

      previousLong = nextLong;
  }

  // next sequenceSet02
  iter = sequenceSet02.iterator();
  previousLong = (Long) iter.next();
  while (iter.hasNext()) {
      Long nextLong = (Long) iter.next();
      logger.log(Level.FINE, "previousID = " + previousLong +
            " nextID = " + nextLong);
      long delta = nextLong.longValue() - previousLong.longValue();
      if (delta != 1) {
    String message = "Event sequence numbers are not" +
        " strictly increasing for listener #2.";
    throw new TestException(message);
      }

      previousLong = nextLong;
  }

  /* assert that there is no overlap in the event sequence numbers.
     Strictly speaking there can be an overlap because it is valid
     for the LRS to send the same event twice (for example in the
     case where a partial failure exists). If there is an overlap,
     we will allow it if and only if the leases encapsulated by
     the two events are the same (ergo, the events are the same). */
  iter = sequenceSet01.iterator();
  while (iter.hasNext()) {
      Long nextLong = (Long) iter.next();

      if (sequenceSet02.contains(nextLong) &&
    (notSameEvent(events01, events02, nextLong.longValue()))) {
    String message = "Event sequence numbers overlap between" +
        " listener #1 and listener #2.";
    throw new TestException(message);
      }
  }      
    }

    /**
     * Determines if two renewal failure events with the same sequence
     * number are in fact different events.
     *
     * <P>Notes:</P>
     *
     * @param set01  Set containing the sequence numbers (sorted).
     * @param evtArr01 An array containg events whose sequence numbers are in
     *                 set01.
     * @param set02  Set containing the sequence numbers (sorted).
     * @param evtArr02 An array containg events whose sequence numbers are in
     *                 set02.
     * @param seqNum The sequence number that is overlapping in the sets.
     *
     * @return true if the overlap involves two different events with the
     *              same sequence number. false otherwise.
     *
     */
    private boolean notSameEvent(RemoteEvent[] evtArr01,
         RemoteEvent[] evtArr02, long seqNum)
                throws IOException, ClassNotFoundException {
  int evtIndex01 = indexOf(evtArr01, seqNum);
  int evtIndex02 = indexOf(evtArr02, seqNum);
  /* we assume the above two calls will always return a non-negative
     number since this is a private method only used in this class. */

  // capture the two event whose sequence numbers overlap
  RenewalFailureEvent evt01 = (RenewalFailureEvent) evtArr01[evtIndex01];
  RenewalFailureEvent evt02 = (RenewalFailureEvent) evtArr02[evtIndex02];
 
  // they are the same if the leases that failed are the same
  Lease lease01 = evt01.getLease();
  Lease lease02 = evt02.getLease();

  // return the truth of the matter
  return lease01.equals(lease02) == false;
    }

    /**
     * Return the index in the event array where the sequenceNumber is found.
     *
     * @param eventArr the array of RemoteEvent containing events for search.
     * @param sequenceNumber the sequence number of the event whose index is
     *                       sought in the array.
     *
     * @return the index in eventArr where sequenceNumber is located or -1
     *         if not found.
     *
     */
    private int indexOf(RemoteEvent[] eventArr, long sequenceNumber) {
  for(int i = 0; i < eventArr.length; ++i) {
      if (eventArr[i].getSequenceNumber() == sequenceNumber) {
    return i;
      }
  }

  // no can find (in the context of this test we should never be here)
  return -1;
    }

} // EventSequenceFailTest












TOP

Related Classes of com.sun.jini.test.spec.renewalservice.EventSequenceFailTest

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.