You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by pe...@apache.org on 2013/01/02 06:21:08 UTC

svn commit: r1427655 [20/35] - in /river/jtsk/skunk/qa_refactor/trunk/qa: ./ doc/ src/com/sun/jini/qa/harness/ src/com/sun/jini/test/impl/discoverymanager/ src/com/sun/jini/test/impl/discoveryproviders/ src/com/sun/jini/test/impl/end2end/e2etest/ src/c...

Added: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/LookupServices.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/LookupServices.java?rev=1427655&view=auto
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/LookupServices.java (added)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/LookupServices.java Wed Jan  2 05:20:52 2013
@@ -0,0 +1,1286 @@
+/*
+ * 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.share;
+
+import com.sun.jini.qa.harness.AdminManager;
+import com.sun.jini.qa.harness.QAConfig;
+import com.sun.jini.qa.harness.TestException;
+import com.sun.jini.test.share.BaseQATest.LocatorGroupsPair;
+import com.sun.jini.test.share.BaseQATest.LookupListener;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.rmi.RemoteException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import net.jini.admin.Administrable;
+import net.jini.core.discovery.LookupLocator;
+import net.jini.core.lookup.ServiceRegistrar;
+import net.jini.discovery.DiscoveryGroupManagement;
+import net.jini.discovery.DiscoveryManagement;
+import net.jini.lookup.DiscoveryAdmin;
+
+/**
+ *
+ * @author peter
+ */
+public class LookupServices {
+    /** the logger */
+    private static final Logger logger = 
+    Logger.getLogger("com.sun.jini.qa.harness");
+    /* instance variables not modified after construction */
+    private final QAConfig config;
+    private final AdminManager manager;
+    private final String implClassname;
+    private final int testType;
+    private final boolean debugsync;
+    
+    private volatile int maxSecsEventWait = 600;
+    private final int originalAnnounceInterval;
+    private final int announceInterval;
+    private final int minNAnnouncements;
+    private final int nIntervalsToWait;
+
+    private final int nLookupServices;
+    private final int nAddLookupServices;
+    private final int nRemoteLookupServices;
+    private final int nAddRemoteLookupServices;
+    private final int nSecsLookupDiscovery;
+    private final int nSecsServiceDiscovery;
+    private final int nSecsJoin;
+    
+    private final int nServices;//local/serializable test services
+    private volatile int nAddServices;//additional local/serializable services
+
+
+    /* Attributes per service */
+    private final int nAttributes;
+    private final int nAddAttributes;
+
+    private final String remoteHost;
+
+    /* Data structures - lookup services */
+    private final Object lock = new Object(); // synchronizes state of all List<LocatorGroupsPair> after construction.
+    private final List<LocatorGroupsPair> initLookupsToStart = new ArrayList<LocatorGroupsPair>(11);
+    private final List<LocatorGroupsPair> addLookupsToStart  = new ArrayList<LocatorGroupsPair>(11);
+    private final List<LocatorGroupsPair> allLookupsToStart  = new ArrayList<LocatorGroupsPair>(11);
+    private final List<LocatorGroupsPair> lookupsStarted    = new ArrayList<LocatorGroupsPair>(11);
+    // end lock scope.
+
+    private final List<ServiceRegistrar> lookupList = new ArrayList<ServiceRegistrar>(1);//synchronize on lookupList
+    private final ConcurrentMap<Object, String[]> genMap = new ConcurrentHashMap<Object, String[]>(11);
+
+    /* Need to keep track of member groups by the index of the corresponding
+     * lookup service so those groups can be mapped to the correct member
+     * groups configuration item. 
+     */
+    private final List<String[]> memberGroupsList = new ArrayList<String[]>(11);//built during construction, no mutation after.
+    
+    /* Need to keep a local mapping of registrars to their corresponding 
+     * locators and groups so that when a registrar is discarded (indicating
+     * that a remote call to retrieve the discarded registrar's locator and/or
+     * group information should not be made), the locator and/or groups can
+     * be retrieved through a non-remote mechanism. Each time a lookup service
+     * is started, the registrar and its locator/groups pair are added to this
+     * map.
+     */
+    private ConcurrentMap<ServiceRegistrar,LocatorGroupsPair> regsToLocGroupsMap = 
+            new ConcurrentHashMap<ServiceRegistrar,LocatorGroupsPair>(11);
+
+    LookupServices(QAConfig config, AdminManager manager, int fastTimeout) throws TestException{
+        this.config = config;
+        this.manager = manager;
+        debugsync = config.getBooleanConfigVal("qautil.debug.sync",false);
+        testType = config.getIntConfigVal("com.sun.jini.testType",
+                                       BaseQATest.AUTOMATIC_LOCAL_TEST);
+        /* begin harness info */
+        logger.log(Level.FINE, " ----- Harness Info ----- ");
+        String harnessCodebase = System.getProperty("java.rmi.server.codebase",
+                                                    "no codebase");
+        logger.log(Level.FINE, " harness codebase         -- {0}", harnessCodebase);
+
+        String harnessClasspath = System.getProperty("java.class.path",
+                                                    "no classpath");
+        logger.log(Level.FINE, " harness classpath        -- {0}", harnessClasspath);
+
+        String discDebug = System.getProperty("net.jini.discovery.debug",
+                                              "false");
+        logger.log(Level.FINE, " net.jini.discovery.debug        -- {0}", discDebug);
+        String regDebug = System.getProperty("com.sun.jini.reggie.proxy.debug",
+                                             "false");
+        logger.log(Level.FINE, " com.sun.jini.reggie.proxy.debug -- {0}", regDebug);
+        String joinDebug = System.getProperty("com.sun.jini.join.debug",
+                                              "false");
+        logger.log(Level.FINE, " com.sun.jini.join.debug         -- {0}", joinDebug);
+        String sdmDebug = System.getProperty("com.sun.jini.sdm.debug","false");
+        logger.log(Level.FINE, " com.sun.jini.sdm.debug          -- {0}", sdmDebug);
+
+        /* end harness info */
+
+        /* begin lookup info */
+        logger.log(Level.FINE, " ----- Lookup Service Info ----- ");
+        implClassname = config.getStringConfigVal
+                                 ("net.jini.core.lookup.ServiceRegistrar.impl",
+                                  "no implClassname");
+        int nLuServ = 0;
+        nLuServ = config.getIntConfigVal
+                           ("net.jini.lookup.nLookupServices",
+                             nLuServ);
+        int nRemLuServ = 0;
+        nRemLuServ = config.getIntConfigVal
+                           ("net.jini.lookup.nRemoteLookupServices",
+                             nRemLuServ);
+        int nAddLuServ = 0;
+        nAddLuServ = config.getIntConfigVal
+                           ("net.jini.lookup.nAddLookupServices",
+                             nAddLuServ);
+        int nAddRemLuServ = 0;
+        nAddRemLuServ = config.getIntConfigVal
+                           ("net.jini.lookup.nAddRemoteLookupServices",
+                             nAddRemLuServ);
+        if(testType == BaseQATest.MANUAL_TEST_REMOTE_COMPONENT) {
+            nLuServ = nRemLuServ;
+            nAddLuServ = nAddRemLuServ;
+            nRemLuServ = 0;
+            nAddRemLuServ = 0;
+        }//endif
+        this.nLookupServices = nLuServ;
+        this.nRemoteLookupServices = nRemLuServ;
+        this.nAddRemoteLookupServices = nAddRemLuServ;
+        this.nAddLookupServices = nAddLuServ;
+        nSecsLookupDiscovery = config.getIntConfigVal("net.jini.lookup.nSecsLookupDiscovery", 30);
+        logger.log(Level.FINE, " # of lookup services to start            -- {0}", nLuServ);
+        logger.log(Level.FINE, " # of additional lookup services to start -- {0}", nAddLuServ);
+        logger.log(Level.FINE, " seconds to wait for discovery            -- {0}", nSecsLookupDiscovery);
+        /* Multicast announcement info - give priority to the command line */
+        int annInterval = 2 * 60 * 1000;
+        int originalAnnounceInterval = 0;
+        try {
+            int sysInterval = Integer.getInteger
+                                 ("net.jini.discovery.announce",0).intValue();
+            originalAnnounceInterval = sysInterval;
+            if(sysInterval > 0) {
+                annInterval = sysInterval;
+            } else {
+                sysInterval = config.getIntConfigVal
+                                           ("net.jini.discovery.announce",0);
+                if(sysInterval > 0) annInterval = sysInterval;
+            }
+            Properties props = System.getProperties();
+            props.put("net.jini.discovery.announce",
+                       (new Integer(annInterval)).toString());
+            System.setProperties(props);
+        } catch (SecurityException e) {
+            // Ignore
+        } finally {
+            this.announceInterval = annInterval;
+            this.originalAnnounceInterval = originalAnnounceInterval;
+        }
+        logger.log(Level.FINE, " discard if no announcements in (nSecs =) -- {0}", (annInterval/1000));
+        minNAnnouncements = config.getIntConfigVal
+                         ("net.jini.discovery.minNAnnouncements", 2);
+        nIntervalsToWait = config.getIntConfigVal
+                          ("net.jini.discovery.nIntervalsToWait", 3);
+        /* end lookup info */
+
+        fastTimeout = 
+            config.getIntConfigVal("com.sun.jini.test.share.fastTimeout", 
+                                 fastTimeout);
+
+        /* begin local/serializable service info */
+        nServices = config.getIntConfigVal("net.jini.lookup.nServices",0);
+        nAddServices = config.getIntConfigVal("net.jini.lookup.nAddServices",0);
+        int nAttr = 0;
+        int nAddAttr = 0;
+        int nSecJoin = 30;
+        int nSecServiceDiscovery = 30;
+        if( (nServices+nAddServices) > 0) {
+            nAttr = config.getIntConfigVal("net.jini.lookup.nAttributes",nAttr);
+            nAddAttr = config.getIntConfigVal("net.jini.lookup.nAddAttributes", nAddAttr);
+            nSecJoin = config.getIntConfigVal("net.jini.lookup.nSecsJoin", nSecJoin);
+            nSecServiceDiscovery = config.getIntConfigVal("net.jini.lookup.nSecsServiceDiscovery", nSecServiceDiscovery);
+            logger.log(Level.FINE, " ----- General Service Info ----- ");
+            logger.log(Level.FINE, " # of initial basic services to register  -- {0}", nServices);
+            logger.log(Level.FINE, " # of additional basic srvcs to register  -- {0}", nAddServices);
+            logger.log(Level.FINE, " # of attributes per service              -- {0}", nAttr);
+            logger.log(Level.FINE, " # of additional attributes per service   -- {0}", nAddAttr);
+            logger.log(Level.FINE, " # of seconds to wait for service join    -- {0}", nSecJoin);
+            logger.log(Level.FINE, " # of secs to wait for service discovery  -- {0}", nSecServiceDiscovery);
+        }//endif(nServices+nAddServices > 0)
+        this.nAttributes = nAttr;
+        this.nAddAttributes = nAddAttr;
+        this.nSecsJoin = nSecJoin;
+        this.nSecsServiceDiscovery = nSecServiceDiscovery;
+        /* Handle remote/local components of manual tests */
+        remoteHost = config.getStringConfigVal("net.jini.lookup.remotehost",
+                                            "UNKNOWN_HOST");
+        switch(testType) {
+            case BaseQATest.MANUAL_TEST_REMOTE_COMPONENT:
+                logger.log(Level.FINE, " ***** REMOTE COMPONENT OF A MANUAL TEST "
+                        +"(remote host = {0}) ***** ", remoteHost);
+                break;
+            case BaseQATest.MANUAL_TEST_LOCAL_COMPONENT:
+                logger.log(Level.FINE, " ***** LOCAL COMPONENT OF A MANUAL TEST "
+                        +"(remote host = {0}) ***** ", remoteHost);
+                logger.log(Level.FINE, " ----- Remote Lookup Service Info ----- ");
+                logger.log(Level.FINE, " # of remote lookup services              -- {0}", nRemoteLookupServices);
+                logger.log(Level.FINE, " # of additional remote lookup services   -- {0}", nAddRemoteLookupServices);
+                logger.log(Level.FINE, " # of remote basic services               -- {0}", nServices);
+                break;
+        }//end switch(testType)
+        
+        /** Retrieves and stores the information needed to configure any lookup
+         *  services that will be started for the current test run.
+         */
+
+        /* Retrieve the member groups & locator of each lookup */
+        /* For all cases except MANUAL_TEST_LOCAL_COMPONENT, the number of
+         * remote lookups is zero (see getSetupInfo). For that case, we must
+         * handle the remote lookup services BEFORE handling the local lookups.
+         * This is because the local component may be both starting local
+         * lookups, and discovering remote lookups; but the remote component
+         * will only be starting the remote lookups, and will therefore have
+         * no knowledge of the local lookups. Because the groups and ports are
+         * ordered by the index numbers in the config file, if the local info
+         * were to be handled first, then the local component of the test
+         * would fall out of alignment with the remote component.
+         */
+        int n0 = 0;
+        int n1 = n0 + nRemLuServ;
+        for(int i=0;i<n1;i++) {//initial remote lookups
+            /* Member groups for remote lookup service i */
+            String groupsArg = config.getServiceStringProperty
+                                    ("net.jini.core.lookup.ServiceRegistrar",
+                                     "membergroups", i);
+            /* Do NOT use unique groups names since clocks on the local
+             * and remote sides are not synchronized, and host names are
+             * different
+             */
+            String[] memberGroups = config.parseString(groupsArg,",");
+            if(memberGroups == DiscoveryGroupManagement.ALL_GROUPS) {
+                logger.log(Level.FINER, "memberGroups = ALL_GROUPS");
+                continue;
+            }
+            memberGroupsList.add(memberGroups);
+            /* Locator for initial remote lookup service i */
+            initLookupsToStart.add
+                          (getLocatorGroupsPair(i,memberGroups));
+        }//end loop
+        /* Remote lookups started after initial remote lookups */
+        n0 = n1;
+        n1 = n0 + nAddRemLuServ;
+        for(int i=n0;i<n1;i++) {//additional remote lookups
+            /* Member groups for remote lookup service i */
+            String groupsArg = config.getServiceStringProperty
+                                    ("net.jini.core.lookup.ServiceRegistrar",
+                                     "membergroups", i);
+            /* Use NON-unique groups for remote lookups */
+            String[] memberGroups = config.parseString(groupsArg,",");
+            if(memberGroups == DiscoveryGroupManagement.ALL_GROUPS) continue;
+            memberGroupsList.add(memberGroups);
+            /* Locator for additional remote lookup service i */
+            addLookupsToStart.add
+                          (getLocatorGroupsPair(i,memberGroups));
+        }//end loop
+        /* Handle all lookups to be started locally */
+        n0 = n1;
+        n1 = n0 + nLuServ;
+        int portBias = n0;
+        for(int i=n0;i<n1;i++) {//initial local lookups
+            /* Member groups for lookup service i */
+            String groupsArg = config.getServiceStringProperty
+                                    ("net.jini.core.lookup.ServiceRegistrar",
+                                     "membergroups", i);
+            if(testType == BaseQATest.AUTOMATIC_LOCAL_TEST) {
+                /* Use unique group names to avoid conflict with other tests */
+                groupsArg = config.makeGroupsUnique(groupsArg);
+            }//endif
+            String[] memberGroups = config.parseString(groupsArg,",");
+            if(memberGroups == DiscoveryGroupManagement.ALL_GROUPS) {
+                logger.log(Level.FINER, "memberGroups = All_Groups");
+                continue;
+            }
+            memberGroupsList.add(memberGroups);
+            /* Locator for initial lookup service i */
+            initLookupsToStart.add
+                          (getLocatorGroupsPair(i-portBias,memberGroups));
+        }//end loop
+        /* The lookup services to start after the initial lookup services */
+        n0 = n1;
+        n1 = n0 + nAddLuServ;
+        for(int i=n0;i<n1;i++) {//additional local lookups
+            /* Member groups for lookup service i */
+            String groupsArg = config.getServiceStringProperty
+                                    ("net.jini.core.lookup.ServiceRegistrar",
+                                     "membergroups", i);
+            if(testType == BaseQATest.AUTOMATIC_LOCAL_TEST) {
+                /* Use unique group names to avoid conflict with other tests */
+                groupsArg = config.makeGroupsUnique(groupsArg);
+            }//endif
+            String[] memberGroups = config.parseString(groupsArg,",");
+            if(memberGroups == DiscoveryGroupManagement.ALL_GROUPS) continue;
+            memberGroupsList.add(memberGroups);
+            /* Locator for additional lookup service i */
+            addLookupsToStart.add
+                          (getLocatorGroupsPair(i-portBias,memberGroups));
+        }//end loop
+        /* Populate the ArrayList allLookupsToStart */
+        for(int i=0;i<initLookupsToStart.size();i++) {
+            allLookupsToStart.add(initLookupsToStart.get(i));
+        }//end loop
+        for(int i=0;i<addLookupsToStart.size();i++) {
+            allLookupsToStart.add(addLookupsToStart.get(i));
+        }//end loop
+
+    }
+
+    /** Convenience method that can be used to start, at a single point 
+     *  during the current test run, all of the lookup services INITIALLY
+     *  needed by that test run. Useful when an initial set of lookups are
+     *  to be started during construct processing, and (possibly) an additional
+     *  set of lookups are to be started at some later time, after the test
+     *  has already begun execution.
+     * @throws Exception 
+     */
+    void startInitLookups() throws Exception {
+        if(nLookupServices > 0) {
+            /* Skip over remote lookups to the indices of the local lookups */
+            int n0 = nRemoteLookupServices + nAddRemoteLookupServices;
+            int n1 = n0 + nLookupServices;
+            synchronized (lock){
+                for(int i=n0;i<n1;i++) {
+                    LocatorGroupsPair pair = initLookupsToStart.get(i);
+                    int port = (pair.getLocator()).getPort();
+                    if(portInUse(port)) port = 0;
+                    String hostname = startLookup(i,port, pair.getLocator().getHost());
+                    logger.log(Level.FINEST, "service host is ''{0}'', this host is ''{1}''", new Object[]{hostname, config.getLocalHostName()});
+                    if(port == 0) {
+                        LocatorGroupsPair locGroupsPair = lookupsStarted.get(i);
+                        initLookupsToStart.set(i,locGroupsPair);
+                        allLookupsToStart.set(i,locGroupsPair);
+                    }
+                    LocatorGroupsPair p = initLookupsToStart.get(i);
+                    LookupLocator l = p.getLocator();
+                    logger.log(Level.FINEST, "init locator {0} = {1}", new Object[]{i, l});
+                }//end loop
+                if(testType != BaseQATest.MANUAL_TEST_LOCAL_COMPONENT) {
+                    if(!BaseQATest.listsEqual(initLookupsToStart,lookupsStarted)) {
+                        logger.log(Level.FINE,
+                                          " initial lookups started != "
+                                          +"initial lookups wanted");
+                        logger.log(Level.FINE,
+                                          " initial lookups started --");
+                        displayLookupStartInfo(lookupsStarted);
+                        logger.log(Level.FINE,
+                                          " initial lookups wanted --");
+                        displayLookupStartInfo(initLookupsToStart);
+    //                    tearDown(); //Have caller perform tearDown.
+                        throw new TestException("initial lookups started != "
+                                                  +"initial lookups wanted");
+                    }//endif
+                }//endif
+            }// end synchronized lock.
+        }//endif(nLookupServices > 0)
+    }//end startInitLookups
+
+    /** Convenience method that can be used to start, at a single point 
+     *  during the current test run, any additional lookup services 
+     *  needed by that test run. Useful when an initial set of lookups are
+     *  to be started during construct processing, and an additional set of
+     *  lookups are to be started at some later time, after the test
+     *  has already begun execution.
+     * @throws Exception 
+     * @throws TestException
+     */
+    void startAddLookups() throws Exception {
+        if(nAddLookupServices > 0) {
+            /* Skip over remote lookups and lookups already started to the
+             * indices of the additional local lookups
+             */
+            int n0 = nRemoteLookupServices + nAddRemoteLookupServices
+                                           + lookupsStarted.size();
+            int n1 = n0 + nAddLookupServices;
+            synchronized (lock){
+                for(int i=n0;i<n1;i++) {
+                    int j = i-n0;
+                    LocatorGroupsPair pair = addLookupsToStart.get(j);
+                    int port = (pair.getLocator()).getPort();
+                    if(portInUse(port)) port = 0;
+                    startLookup(i,port, pair.getLocator().getHost());
+                    if(port == 0) {
+                        LocatorGroupsPair locGroupsPair = lookupsStarted.get(i);
+                        addLookupsToStart.set(j,locGroupsPair);
+                        allLookupsToStart.set(i,locGroupsPair);
+                    }
+                    LocatorGroupsPair p = addLookupsToStart.get(j);
+                    LookupLocator l = p.getLocator();
+                    logger.log(Level.FINEST, "add locator {0} = {1}", new Object[]{j, l});
+                }//end loop
+                if(testType != BaseQATest.MANUAL_TEST_LOCAL_COMPONENT) {
+                    if(!BaseQATest.listsEqual(allLookupsToStart,lookupsStarted)) {
+                        logger.log(Level.FINE,
+                                          " additional lookups started != "
+                                          +"additional lookups wanted");
+                        logger.log(Level.FINE,
+                                          " additional lookups started --");
+                        displayLookupStartInfo(lookupsStarted);
+                        logger.log(Level.FINE,
+                                          " additional lookups wanted --");
+                        displayLookupStartInfo(allLookupsToStart);
+    //                    tearDown(); let caller perform tear down.
+                        throw new TestException("additional lookups started != "
+                                                  +"additional lookups wanted");
+                    }//endif
+                }//endif
+            }// end synchronized lock.
+        }//endif(nAddLookupServices > 0)
+    }//end startAddLookups
+
+    /** 
+     * Start a lookup service with configuration referenced by the
+     * given parameter values.
+     *
+     * @param indx the index of lookup services within the set of
+     *             lookups to start for this test
+     * @param port the port the lookup service is to use
+     * @param serviceHost the host name the lookup service is to use.
+     * @return the name of the system the lookup service was started on
+     * @throws Exception if something goes wrong
+     */
+    protected String startLookup(int indx, int port, String serviceHost) throws Exception {
+        logger.log(Level.FINE, " starting lookup service {0}", indx);
+        /* retrieve the member groups with which to configure the lookup */
+        String[] memberGroups = memberGroupsList.get(indx);
+        ServiceRegistrar lookupProxy = null;
+	String simulatorName = 
+	    "com.sun.jini.test.services.lookupsimulator.LookupSimulatorImpl";
+        if(implClassname.equals(simulatorName)) {
+            DiscoveryProtocolSimulator generator = null;
+            if(debugsync) logger.log(Level.FINE,
+                              "     BaseQATest.startLookup - "
+                              +"sync on lookupList --> requested");
+            synchronized(lookupList) {
+                if(debugsync) logger.log(Level.FINE,
+                                  "     BaseQATest.startLookup - "
+                                  +"sync on lookupList --> granted");
+                /* Use either a random or an explicit locator port */
+                generator = new DiscoveryProtocolSimulator
+                                               (config,memberGroups, manager, port);
+                genMap.put( generator, memberGroups );
+                lookupProxy = generator.getLookupProxy();
+                lookupList.add( lookupProxy );
+                if(debugsync) logger.log(Level.FINE,
+                                  "     BaseQATest.startLookup - "
+                                  +"  added new proxy to lookupList");
+                if(debugsync) logger.log(Level.FINE,
+                                  "     BaseQATest.startLookup - "
+                                  +"sync on lookupList --> released");
+            }//end sync(lookupList)
+            /* Force non-unique groups for manual tests */
+            if(    (testType == BaseQATest.MANUAL_TEST_REMOTE_COMPONENT)
+                || (testType == BaseQATest.MANUAL_TEST_LOCAL_COMPONENT) ) 
+            {
+                generator.setMemberGroups(memberGroups);
+            }//endif
+        } else {//start a non-simulated lookup service implementation
+            if(debugsync) logger.log(Level.FINE,
+                              "     BaseQATest.startLookup - "
+                              +"sync on lookupList --> requested");
+            synchronized(lookupList) {
+                if(debugsync) logger.log(Level.FINE,
+                                  "     BaseQATest.startLookup - "
+                                  +"sync on lookupList --> granted");
+		/* returned proxy is already prepared */
+                lookupProxy = manager.startLookupService(serviceHost);
+                lookupList.add( lookupProxy );
+                if(debugsync) logger.log(Level.FINE,
+                                  "     BaseQATest.startLookup - "
+                                  +"  added new proxy to lookupList");
+                if(debugsync) logger.log(Level.FINE,
+                                  "     BaseQATest.startLookup - "
+                                  +"sync on lookupList --> released");
+            }//end sync(lookupList)
+            genMap.put( lookupProxy, memberGroups );
+            /* Force non-unique groups for manual tests */
+            if(    (testType == BaseQATest.MANUAL_TEST_REMOTE_COMPONENT)
+                || (testType == BaseQATest.MANUAL_TEST_LOCAL_COMPONENT) ) 
+            {
+                if(lookupProxy instanceof Administrable) {
+                    Object admin = ((Administrable)lookupProxy).getAdmin();
+		    admin = config.prepare("test.reggieAdminPreparer", 
+						admin);
+                    if(admin instanceof DiscoveryAdmin) {
+                        ((DiscoveryAdmin)admin).setMemberGroups(memberGroups);
+                    }
+                }
+            }
+        }
+
+        LookupLocator lookupLocator = 
+	    QAConfig.getConstrainedLocator(lookupProxy.getLocator());
+        LocatorGroupsPair locGroupsPair = new LocatorGroupsPair(lookupLocator,
+                                                               memberGroups);
+        synchronized (lock){
+            try {
+                lookupsStarted.add(indx,locGroupsPair);
+            } catch(IndexOutOfBoundsException e) {
+                /* There must be remote lookups, simply add it without the index */
+                lookupsStarted.add(locGroupsPair);
+            }
+        }
+        regsToLocGroupsMap.put(lookupProxy,locGroupsPair);
+
+        LocatorsUtil.displayLocator(lookupLocator,
+                                    "  locator",Level.FINE);
+        logger.log(Level.FINE, "   memberGroup(s) = {0}", GroupsUtil.toCommaSeparatedStr(memberGroups));
+	return serviceHost;
+    }
+    
+    /** Method that compares the given port to the ports of all the lookup
+     *  services that have been currently started. Returns <code>true</code>
+     *  if the given port equals any of the ports referenced in the set
+     *  lookup services that have been started; <code>false</code>
+     *  otherwise. This method is useful for guaranteeing unique port
+     *  numbers when starting lookup services.
+     * @param port
+     * @return true if port in use. 
+     */
+    public boolean portInUse(int port) {
+        assert Thread.holdsLock(lock);
+        for(int i=0;i<lookupsStarted.size();i++) {
+            LocatorGroupsPair pair = lookupsStarted.get(i);
+            int curPort = (pair.getLocator()).getPort();
+            if(port == curPort) return true;
+        }//end loop
+        return false;
+    }//end portInUse
+    
+    private LocatorGroupsPair getLocatorGroupsPair(int indx, String[] groups) throws TestException {
+        LookupLocator l = getTestLocator(indx);
+        return new BaseQATest.LocatorGroupsPair(l, groups);
+    }
+    
+    /** Constructs a <code>LookupLocator</code> using configuration information
+     *  corresponding to the value of the given parameter <code>indx</code>.
+     *  Useful when lookup services need to be started, or simply when
+     *  instances of <code>LookupLocator</code> need to be constructed with
+     *  meaningful state.
+     * @param indx
+     * @return 
+     * @throws TestException  
+     */
+    public LookupLocator getTestLocator(int indx) throws TestException {
+        /* Locator for lookup service corresponding to indx */
+        int port = config.getServiceIntProperty
+                                    ("net.jini.core.lookup.ServiceRegistrar",
+                                     "port", indx);
+        if (port == Integer.MIN_VALUE) {
+	    port = 4160;
+	}
+	String hostname = 
+	    config.getServiceHost("net.jini.core.lookup.ServiceRegistrar", indx, null);
+	logger.log(Level.FINER, "getServiceHost returned {0}", hostname);
+	if (hostname == null) {
+	    hostname = "localhost";
+	    try {
+		hostname = InetAddress.getLocalHost().getHostName();
+	    } catch(UnknownHostException e) {
+		e.printStackTrace();
+	    }
+	}
+        return QAConfig.getConstrainedLocator(hostname,port);
+    }//end getTestLocator
+    
+    /** Constructs a <code>LookupLocator</code> using configuration information
+     *  corresponding to the value of the given parameter <code>indx</code>.
+     *  Useful when lookup services need to be started, or simply when
+     *  instances of <code>LookupLocator</code> need to be constructed with
+     *  meaningful state.
+     */
+    protected LookupLocator getRemoteTestLocator(int indx) {
+        /* Locator for lookup service corresponding to indx */
+        int port = config.getServiceIntProperty
+                                    ("net.jini.core.lookup.ServiceRegistrar",
+                                     "port", indx);
+        if (port == Integer.MIN_VALUE) {
+	    port = 4160;
+	}
+	// used for book keeping only, so don't need a constrainable locator
+        return QAConfig.getConstrainedLocator(remoteHost,port);
+    }//end getRemoteTestLocator
+
+    /** Method used for debugging. Displays the following information about
+     *  the contents of the given list of <code>LocatorGroupsPair</code>
+     *  instances: the number of elements, the locator of the associated
+     *  lookup service, and the member groups of the associated lookup service.
+     */
+    private void displayLookupStartInfo(List<LocatorGroupsPair> lookupList) {
+        logger.log(Level.FINE, "   # of lookups = {0}", lookupList.size());
+        for(int i=0;i<lookupList.size();i++) {
+            LocatorGroupsPair pair = lookupList.get(i);
+            LookupLocator loc    = pair.getLocator();
+            String[]      groups = pair.getGroups();
+            logger.log(Level.FINE, "     locator lookup[{0}] = {1}", new Object[]{i, loc});
+            GroupsUtil.displayGroupSet(groups,"       group", Level.FINE);
+        }//end loop
+    }//end displayLookupStartInfo
+
+    
+    /** Since the lookup discovery utility typically sends a unicast
+     *  announcement at startup, resulting in immediate discovery by
+     *  unicast, the lookup service which generates the multicast 
+     *  announcements won't send its first announcement until after
+     *  net.jini.discovery.announce number of milliseconds. This means
+     *  that until that first multicast announcement arrives, the lookup
+     *  discovery utility will have no point of reference (no initial time
+     *  stamp) with which to determine if the announcements have indeed
+     *  stopped. Thus, multicast monitoring doesn't really begin until after
+     *  the first announcement arrives. It is for this reason that before
+     *  the multicast announcements are stopped, it may be of value to wait
+     *  enough time so as to guarantee that at least one announcement has
+     *  been sent. This method can be used by tests that wish to provide
+     *  such a guarantee.
+     *
+     *  The time this method waits is computed from the configurable number
+     *  of announcement time intervals over which to wait (nIntervalsToWait),
+     *  and the configurable minimum number of announcements over which
+     *  unreachability is determined (minNAnnouncements).
+     * 
+     *  Note that this method should only be used when the test uses
+     *  simulated lookup services.
+     */
+    protected void verifyAnnouncementsSent() {
+        logger.log(Level.FINE, " number of announcements to wait for    -- {0}", minNAnnouncements);
+        logger.log(Level.FINE, " number of intervals to wait through    -- {0}", nIntervalsToWait);
+        Iterator iter = genMap.keySet().iterator();
+        for(int i=0;iter.hasNext();i++) {
+            DiscoveryProtocolSimulator curGen = 
+                                  (DiscoveryProtocolSimulator)iter.next();
+            logger.log(Level.FINE, " gen {0} - waiting ... announcements so far -- {1}", new Object[]{i, curGen.getNAnnouncementsSent()});
+            for(int j=0; ((j<nIntervalsToWait)
+                &&(curGen.getNAnnouncementsSent()< minNAnnouncements));j++)
+            {
+                DiscoveryServiceUtil.delayMS(announceInterval);
+                logger.log(Level.FINE, " gen {0} - waiting ... announcements so far -- {1}", new Object[]{i, curGen.getNAnnouncementsSent()});
+            }//end loop
+            logger.log(Level.FINE, " gen {0} - wait complete ... announcements  -- {1}", new Object[]{i, curGen.getNAnnouncementsSent()});
+        }//end loop
+    }//end verifyAnnouncementsSent
+    
+    
+    /** This method replaces, with the given set of groups, the current
+     *  member groups of the given lookup service (<code>generator</code>).
+     *  This method returns an instance of <code>LocatorGroupsPair</code> in
+     *  which the locator of the given lookup service is paired with the given
+     *  set of new groups.
+     */
+    private LocatorGroupsPair replaceMemberGroups(Object generator,
+                                                    String[] newGroups)
+                                                        throws RemoteException
+    {
+        ServiceRegistrar regProxy = null;
+        if(generator instanceof DiscoveryProtocolSimulator) {
+            regProxy
+                    = ((DiscoveryProtocolSimulator)generator).getLookupProxy();
+            ((DiscoveryProtocolSimulator)generator).setMemberGroups(newGroups);
+        } else {
+            regProxy = (ServiceRegistrar)generator;
+            DiscoveryAdmin admin
+                    = (DiscoveryAdmin)( ((Administrable)regProxy).getAdmin() );
+	    try {
+                admin = (DiscoveryAdmin)
+		        config.prepare("test.reggieAdminPreparer", admin);
+	    } catch (TestException e) {
+		throw new RemoteException("Problem preparing admin", e);
+	    }
+            admin.setMemberGroups(newGroups);
+        }//endif
+        LookupLocator loc = QAConfig.getConstrainedLocator(regProxy.getLocator());
+        return new LocatorGroupsPair(loc,newGroups);
+    }//end replaceMemberGroups
+
+    /** Depending on the value of the boolean parameter <code>alternate</code>,
+     *  this method either replaces the current member groups of the
+     *  given lookup service (<code>generator</code>) with a new set
+     *  of groups containing NONE of the current groups of interest
+     *  (<code>alternate</code> == <code>false</code>), or a new set
+     *  of groups in which, alternately, half the elements are equal
+     *  to their counterparts in the original set, and half are different
+     *  from their counterparts.
+     *  
+     *  This method is intended to guarantee that the new set of groups 
+     *  that replaces the member groups of the given lookup service contains
+     *  some, if not all, new groups different from the original groups.
+     *
+     *  This method returns an instance of  <code>LocatorGroupsPair</code>
+     *  in which the locator of the given lookup service is paired with the
+     *  set of new groups generated by this method.
+     * @param generator
+     * @param alternate 
+     * @return
+     * @throws RemoteException  
+     */
+    private LocatorGroupsPair replaceMemberGroups(Object generator,
+                                                    boolean alternate)
+                                                        throws RemoteException
+    {
+        ServiceRegistrar regProxy = null;
+	DiscoveryAdmin admin = null;
+	// only prepare the real proxy (until simulators are secure)
+        if(generator instanceof DiscoveryProtocolSimulator) {
+            regProxy
+                   = ((DiscoveryProtocolSimulator)generator).getLookupProxy();
+	    admin = (DiscoveryAdmin)( ((Administrable)regProxy).getAdmin() );
+        } else {
+            regProxy = (ServiceRegistrar)generator;
+	    admin = (DiscoveryAdmin)( ((Administrable)regProxy).getAdmin() );
+	    try {
+                admin = (DiscoveryAdmin)
+		        config.prepare("test.reggieAdminPreparer", admin);
+	    } catch (TestException e) {
+		throw new RemoteException("Problem preparing admin", e);
+	    }
+        }//endif
+        String[] groups    = admin.getMemberGroups();
+        String[] newGroups =  ( (groups.length > 0) ? 
+                          (new String[groups.length]) :
+                          (new String[] {"Group_"+regProxy.getServiceID()}) );
+        if(newGroups.length == 0) {
+            logger.log(Level.FINE, "   NO_GROUPS");
+        } else {
+            for(int i=0;i<newGroups.length;i++) {
+                boolean oddIndx = !((i%2) == 0);
+                // This looks dubious, the new String may be replaced with the
+                // original instance by the jvm.
+                newGroups[i] = ( (alternate && oddIndx) ? new String(groups[i])
+                                             : new String(groups[i]+"_new") );
+                logger.log(Level.FINE, "   newGroups["+i+"] = "
+                                           +newGroups[i]);
+            }//end loop
+        }//endif
+        return replaceMemberGroups(generator,newGroups);
+    }//end replaceMemberGroups
+
+    /** Depending on the value of the boolean parameter <code>alternate</code>,
+     *  for each lookup service that has been started, this method either
+     *  replaces the current member groups of the lookup service with a
+     *  new set of groups containing NONE of the current groups of interest
+     *  (<code>alternate</code> == <code>false</code>), or a new set of
+     *  groups in which, alternately, half the elements are equal to their
+     *  counterparts in the original set, and half are different from their
+     *  counterparts.
+     *
+     *  This method is intended to guarantee that the new set of groups 
+     *  that replaces the member groups of each lookup service that was
+     *  started contains some, if not all, new groups different from the
+     *  original groups.
+     *  
+     *  This method returns an <code>ArrayList</code> in which each element
+     *  is an instance of <code>LocatorGroupsPair</code> corresponding to one
+     *  of the lookup services that was started; and in which the locator of
+     *  the associated lookup service is paired with the set of new groups
+     *  generated by this method.
+     *
+     *  This method can be used to cause various discovered/discarded/changed
+     *  events to be sent by the discovery helper utility.
+     * @param alternate
+     * @return  
+     */
+   public List<LocatorGroupsPair> replaceMemberGroups(boolean alternate) {
+        List<LocatorGroupsPair> locGroupsList = new ArrayList<LocatorGroupsPair>(genMap.size());
+        Iterator iter = genMap.keySet().iterator();
+        for(int i=0;iter.hasNext();i++) {
+            /* Replace the member groups of the current lookup service */
+            logger.log(Level.FINE, " lookup service {0}"+" - "
+                              +"replacing member groups with -- ", i);
+            try {
+                locGroupsList.add(replaceMemberGroups(iter.next(),alternate));
+            } catch(RemoteException e) {
+                logger.log(Level.FINE, 
+                                  " failed to change member groups "+"for lookup service {0}", i);
+                e.printStackTrace();
+            }
+        }//end loop
+        return locGroupsList;
+    }//end replaceMemberGroups
+
+
+    /** For each lookup service that has been started, this method replaces
+     *  the lookup service's current member groups with the given set of
+     *  groups.
+     *
+     *  This method returns an <code>ArrayList</code> in which each element
+     *  is an instance of <code>LocatorGroupsPair</code> corresponding to one
+     *  of the lookup services that was started; and in which the locator of
+     *  the associated lookup service is paired with given set of groups.
+    * @param newGroups
+    * @return  
+    */
+   public List<LocatorGroupsPair> replaceMemberGroups(String[] newGroups) {
+        return replaceMemberGroups(genMap.size(),newGroups);
+    }//end replaceMemberGroups
+
+    /** For N of the lookup services started, this method replaces the lookup
+     *  service's current member groups with the given set of groups; where
+     *  N is determined by the value of the given <code>nReplacements</code>
+     *  parameter.
+     *
+     *  This method returns an <code>List</code> in which each element
+     *  is an instance of <code>LocatorGroupsPair</code> corresponding to one
+     *  of the lookup services that was started; and in which the locator of
+     *  the associated lookup service is paired with the given set of groups.
+    * @param nReplacements
+    * @param newGroups 
+    * @return  
+    */
+   public List<LocatorGroupsPair> replaceMemberGroups(int nReplacements,
+                                           String[] newGroups)
+   {
+        List<LocatorGroupsPair> locGroupsList = new ArrayList<LocatorGroupsPair>(genMap.size());
+        Iterator iter = genMap.keySet().iterator();
+        for(int i=0;iter.hasNext();i++) {
+            Object generator = iter.next();
+            if(i<nReplacements) {
+                /* Replace the member groups of the current lookup service */
+                logger.log(Level.FINE, " lookup service {0}"+" - "
+                                  +"replacing member groups with --", i);
+                if(newGroups.length == 0) {
+                    logger.log(Level.FINE, "   NO_GROUPS");
+                } else {
+                    for(int j=0;j<newGroups.length;j++) {
+                        logger.log(Level.FINE, "   newGroups[{0}] = {1}", new Object[]{j, newGroups[j]});
+                    }//end loop
+                }//endif
+                try {
+                    locGroupsList.add
+                                  ( replaceMemberGroups(generator,newGroups) );
+                } catch(RemoteException e) {
+                    logger.log(Level.FINE, 
+                                      " failed to change member groups "+"for lookup service {0}", i);
+                    e.printStackTrace();
+                }
+            } else {//(i >= nReplacements)
+                /* Leave member groups of the current lookup service as is*/
+                logger.log(Level.FINE, " lookup service {0}"+" - "
+                                  +"leaving member groups unchanged --", i);
+                ServiceRegistrar regProxy = null;
+                if(generator instanceof DiscoveryProtocolSimulator) {
+                    regProxy
+                    = ((DiscoveryProtocolSimulator)generator).getLookupProxy();
+                } else {
+                    regProxy = (ServiceRegistrar)generator;
+                }//endif
+                try {
+                    LookupLocator loc = QAConfig.getConstrainedLocator(regProxy.getLocator());
+                    String[] groups   = regProxy.getGroups();
+                    if(groups.length == 0) {
+                        logger.log(Level.FINE, "   NO_GROUPS");
+                    } else {
+                        for(int j=0;j<groups.length;j++) {
+                            logger.log(Level.FINE, "   groups[{0}] = {1}", new Object[]{j, groups[j]});
+                        }//end loop
+                    }//endif
+                    locGroupsList.add
+                                  ( new LocatorGroupsPair(loc,groups) );
+                } catch(RemoteException e) {
+                    logger.log(Level.FINE, 
+                                      " failed on locator/groups retrieval "+"for lookup service {0}", i);
+                    e.printStackTrace();
+                }
+            }//endif
+        }//end loop
+        return locGroupsList;
+    }//end replaceMemberGroups
+
+    /** Convenience method that returns a shallow copy of the
+     *  <code>lookupList</code> <code>ArrayList</code> that contains the
+     *  proxies to the lookup services that have been started so far.
+     *  The size of that list is retrieved while the list is locked, 
+     *  so that the list is not modified while the copy is being made.
+     */
+    public List<ServiceRegistrar> getLookupListSnapshot() {
+        return getLookupListSnapshot(null);
+    }//end getLookupListSnapshot
+
+    public List<ServiceRegistrar> getLookupListSnapshot(String infoStr) {
+        String str = ( (infoStr == null) ? 
+                       "     sync on lookupList --> " :
+                       "     "+infoStr+" - sync on lookupList --> ");
+        if(debugsync) logger.log(Level.FINE, "{0}requested", str);
+        synchronized(lookupList) {
+            if(debugsync) logger.log(Level.FINE, "{0}granted", str);
+            List<ServiceRegistrar> listSnapshot = new ArrayList<ServiceRegistrar>(lookupList.size());
+            for(int i=0;i<lookupList.size();i++) {
+                listSnapshot.add(i,lookupList.get(i));
+            }//end loop
+            if(debugsync) logger.log(Level.FINE, "{0}released", str);
+            return listSnapshot;
+        }//end sync(lookupList)
+    }//end getLookupListSnapshot
+
+    /** Convenience method that returns the current size of the
+     *  <code>lookupList</code> <code>ArrayList</code> that contains the
+     *  proxies to the lookup services that have been started so far.
+     *  The size of that list is retrieved while the list is locked, 
+     *  so that the list is not modified while the retrieval is being made.
+     */
+    public int curLookupListSize() {
+        return curLookupListSize(null);
+    }//end curLookupListSize
+
+    public int curLookupListSize(String infoStr) {
+        String str = ( (infoStr == null) ? 
+                       "     sync on lookupList --> " :
+                       "     "+infoStr+" - sync on lookupList --> ");
+        if(debugsync) logger.log(Level.FINE, str+"requested");
+        synchronized(lookupList) {
+            if(debugsync) logger.log(Level.FINE, str+"granted");
+            int size = lookupList.size();
+            if(debugsync) logger.log(Level.FINE, str+"released");
+            return size;
+        }//end sync(lookupList)
+    }//end curLookupListSize
+  
+    /** Returns the proxy to each lookup service started (already prepared)*/
+    protected ServiceRegistrar[] getLookupProxies() {
+        ServiceRegistrar[] proxies = new ServiceRegistrar[genMap.size()];
+	Iterator iter = genMap.keySet().iterator();
+        for(int i=0;iter.hasNext();i++) {
+            Object curObj = iter.next();
+            if(curObj instanceof DiscoveryProtocolSimulator) {
+                proxies[i]
+                      = ((DiscoveryProtocolSimulator)curObj).getLookupProxy();
+            } else {
+                proxies[i] = (ServiceRegistrar)curObj;
+            }//endif
+        }//end loop
+        return proxies;
+    }//end getLookupProxies
+
+    /** For each lookup service corresponding to an element of the global
+     *  HashMap 'genMap', this method stops the generation of multicast
+     *  announcements by either destroying the lookup service, or 
+     *  explicitly stopping the announcements and then destroying the
+     *  lookup service.
+     *  
+     *  @throws com.sun.jini.qa.harness.TestException
+     */
+    public boolean terminateAllLookups() throws TestException {
+        Iterator iter = genMap.keySet().iterator();
+        for(int i=0;iter.hasNext();i++) {
+            Object curObj = iter.next();
+            ServiceRegistrar regProxy = null;
+            if(curObj instanceof DiscoveryProtocolSimulator) {
+                DiscoveryProtocolSimulator curGen
+                                         = (DiscoveryProtocolSimulator)curObj;
+                regProxy = curGen.getLookupProxy();
+                curGen.stopAnnouncements();
+            } else {
+                regProxy = (ServiceRegistrar)curObj;
+            }//endif
+            /* destroy lookup service i */
+            manager.destroyService(regProxy);
+        }//end loop
+        return true;
+    }//end terminateAllLookups
+
+    /** This method stops the generation of multicast announcements from each
+     *  lookup service that has been started. The announcements are stopped
+     *  directly if possible or, if stopping the announcements directly is not
+     *  possible, the announcements are stopped indirectly by destroying each
+     *  lookup service (ex. reggie does not allow one to stop its multicast
+     *  announcements while allowing the service to remain running and
+     *  reachable.)
+     */
+    public boolean stopAnnouncements() {
+        Iterator iter = genMap.keySet().iterator();
+        for(int i=0;iter.hasNext();i++) {
+            logger.log(Level.FINE, " stop multicast announcements "
+                              +"from lookup service "+i+" ...");
+            Object curObj = iter.next();
+            if(curObj instanceof DiscoveryProtocolSimulator) {
+                DiscoveryProtocolSimulator curGen
+                                         = (DiscoveryProtocolSimulator)curObj;
+                curGen.stopAnnouncements();
+            } else {//cannot stop the announcements, must destroy the lookup
+                /* It's not a simulated LUS, thus the only way to stop the
+                 * announcements is to destroy each LUS individually.
+                 */
+                manager.destroyService((ServiceRegistrar)curObj);
+            }//endif
+        }//end loop
+        return true;
+    }//end stopAnnouncements
+
+    /** For each lookup service proxy contained in the input array, this
+     *  method first determines if that lookup service is reachable by
+     *  attempting to retrieve the associated locator; that is, it
+     *  attempts to 'ping' the lookup service. The lookup services found
+     *  to be un-reachable are then used to update the given listener's
+     *  expected discard state. After updating the listener's expected 
+     *  state, each unreachable lookup service is discarded from the given
+     *  instance of LookupDiscovery.
+     * 
+     *  This method returns an ArrayList containing LocatorGroupsPair
+     *  instances corresponding to the lookups that were NOT discarded.
+     *  This is so that the expected discard event state can be built
+     *  correctly (a discarded event should not be expected for a lookup
+     *  service that couldn't be discarded).
+     */
+    protected ArrayList pingAndDiscard(ServiceRegistrar[] proxies,
+                                       DiscoveryManagement dm,
+                                       LookupListener listener)
+    {
+        ArrayList proxiesToDiscard      = new ArrayList(1);
+        ArrayList locGroupsNotDiscarded = new ArrayList(1);
+        /* Determine proxies to discard and proxies that cannot be discarded */
+        for(int i=0;i<proxies.length;i++) {
+            LocatorGroupsPair curPair
+                      = (LocatorGroupsPair)regsToLocGroupsMap.get(proxies[i]);
+            try {
+                LookupLocator loc = QAConfig.getConstrainedLocator(proxies[i].getLocator());
+                logger.log(Level.FINE, " ");
+                if(curPair != null) {
+                    logger.log(Level.FINE,
+                                      " warning -- lookup service "
+                                      +"is still reachable --> locator = "
+                                      +curPair.getLocator()+"\n");
+                    locGroupsNotDiscarded.add(curPair);
+                } else {
+                    logger.log(Level.FINE,
+                                      " warning -- lookup service "+i
+                                      +" is still reachable\n");
+                }//endif
+            } catch(RemoteException e) {//lookup is un-reachable, discard it
+                proxiesToDiscard.add(proxies[i]);
+            }
+        }//end loop
+        /* Perform the actual discards to generate the discard events */
+        for(int i=0;i<proxiesToDiscard.size();i++) {
+            dm.discard((ServiceRegistrar)proxiesToDiscard.get(i));
+        }//end loop
+        return locGroupsNotDiscarded;//return proxies we couldn't discard
+    }//end pingAndDiscard
+
+    /**
+     * @return the testType
+     */
+    public int getTestType() {
+        return testType;
+    }
+
+    /**
+     * @return the debugsync
+     */
+    public boolean isDebugsync() {
+        return debugsync;
+    }
+
+    /**
+     * @return the maxSecsEventWait
+     */
+    public int getMaxSecsEventWait() {
+        return maxSecsEventWait;
+    }
+
+    /**
+     * @return the announceInterval
+     */
+    public int getAnnounceInterval() {
+        return announceInterval;
+    }
+
+    /**
+     * @return the minNAnnouncements
+     */
+    public int getMinNAnnouncements() {
+        return minNAnnouncements;
+    }
+
+    /**
+     * @return the nIntervalsToWait
+     */
+    public int getnIntervalsToWait() {
+        return nIntervalsToWait;
+    }
+
+    /**
+     * @return the nLookupServices
+     */
+    public int getnLookupServices() {
+        return nLookupServices;
+    }
+
+    /**
+     * @return the nAddLookupServices
+     */
+    public int getnAddLookupServices() {
+        return nAddLookupServices;
+    }
+
+    /**
+     * @return the nRemoteLookupServices
+     */
+    public int getnRemoteLookupServices() {
+        return nRemoteLookupServices;
+    }
+
+    /**
+     * @return the nAddRemoteLookupServices
+     */
+    public int getnAddRemoteLookupServices() {
+        return nAddRemoteLookupServices;
+    }
+
+    /**
+     * @return the nSecsLookupDiscovery
+     */
+    public int getnSecsLookupDiscovery() {
+        return nSecsLookupDiscovery;
+    }
+
+    /**
+     * @return the nSecsServiceDiscovery
+     */
+    public int getnSecsServiceDiscovery() {
+        return nSecsServiceDiscovery;
+    }
+
+    /**
+     * @return the nSecsJoin
+     */
+    public int getnSecsJoin() {
+        return nSecsJoin;
+    }
+
+    /**
+     * @return the nServices
+     */
+    public int getnServices() {
+        return nServices;
+    }
+
+    /**
+     * @return the nAddServices
+     */
+    public int getnAddServices() {
+        return nAddServices;
+    }
+
+    /**
+     * @return the nAttributes
+     */
+    public int getnAttributes() {
+        return nAttributes;
+    }
+
+    /**
+     * @return the nAddAttributes
+     */
+    public int getnAddAttributes() {
+        return nAddAttributes;
+    }
+
+    /**
+     * @return the remoteHost
+     */
+    public String getRemoteHost() {
+        return remoteHost;
+    }
+
+    /**
+     * @return the allLookupsToStart
+     */
+    public List<LocatorGroupsPair> getAllLookupsToStart() {
+        synchronized (lock){
+            List<LocatorGroupsPair> list = new ArrayList<LocatorGroupsPair>(allLookupsToStart.size());
+            list.addAll(allLookupsToStart);
+            return list;
+        }
+    }
+
+    /**
+     * @return the regsToLocGroupsMap
+     */
+    public ConcurrentMap<ServiceRegistrar,LocatorGroupsPair> getRegsToLocGroupsMap() {
+        return regsToLocGroupsMap;
+    }
+
+    /**
+     * @return the genMap
+     */
+    public ConcurrentMap<Object, String[]> getGenMap() {
+        return genMap;
+    }
+
+    /**
+     * @return the initLookupsToStart
+     */
+    public List<LocatorGroupsPair> getInitLookupsToStart() {
+        List<LocatorGroupsPair> lgp = new LinkedList<LocatorGroupsPair>();
+        synchronized (lock){
+            lgp.addAll(initLookupsToStart);
+            return lgp;
+        }
+    }
+
+    /**
+     * @return the addLookupsToStart
+     */
+    public List<LocatorGroupsPair> getAddLookupsToStart() {
+        List<LocatorGroupsPair> lgp = new LinkedList<LocatorGroupsPair>();
+        synchronized (lock){
+            lgp.addAll(addLookupsToStart);
+            return lgp;
+        }
+    }
+
+    /**
+     * @return the lookupsStarted
+     */
+    public List<LocatorGroupsPair> getLookupsStarted() {
+        List<LocatorGroupsPair> lgp = new LinkedList<LocatorGroupsPair>();
+        synchronized (lookupsStarted){
+            lgp.addAll(lookupsStarted);
+            return lgp;
+        }
+    }
+
+    /**
+     * @return the originalAnnounceInterval
+     */
+    public int getOriginalAnnounceInterval() {
+        return originalAnnounceInterval;
+    }
+
+    /**
+     * @param nAddServices the nAddServices to set
+     */
+    public void setnAddServices(int nAddServices) {
+        this.nAddServices = nAddServices;
+    }
+
+}

Propchange: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/LookupServices.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/LookupTestBase.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/LookupTestBase.java?rev=1427655&r1=1427654&r2=1427655&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/LookupTestBase.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/LookupTestBase.java Wed Jan  2 05:20:52 2013
@@ -18,6 +18,7 @@
 
 package com.sun.jini.test.share;
 
+import com.sun.jini.qa.harness.Test;
 import java.util.logging.Level;
 
 // Test harness specific classes
@@ -35,7 +36,7 @@ import net.jini.core.transaction.server.
 /**
  * Base class for tests that thest JoinAdmin related functionality
  */
-public abstract class LookupTestBase extends TestBase {
+public abstract class LookupTestBase extends TestBase implements Test {
     protected Object    service;
     protected Object    admin;
 

Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/RenewingRemoteListener.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/RenewingRemoteListener.java?rev=1427655&r1=1427654&r2=1427655&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/RenewingRemoteListener.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/RenewingRemoteListener.java Wed Jan  2 05:20:52 2013
@@ -32,7 +32,7 @@ import net.jini.lease.LeaseRenewalSet;
 
 import net.jini.export.Exporter;
 
-import com.sun.jini.qa.harness.QATest;
+import com.sun.jini.qa.harness.QATestEnvironment;
 import com.sun.jini.qa.harness.QAConfig;
 import com.sun.jini.qa.harness.TestException;
 

Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/TestBase.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/TestBase.java?rev=1427655&r1=1427654&r2=1427655&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/TestBase.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/TestBase.java Wed Jan  2 05:20:52 2013
@@ -17,11 +17,8 @@
  */
 package com.sun.jini.test.share;
 
-import java.util.logging.Level;
 
 // java.*
-import java.rmi.RMISecurityManager;
-import java.rmi.UnmarshalException;
 import java.rmi.NoSuchObjectException;
 import java.rmi.RemoteException;
 import java.util.List;
@@ -43,25 +40,23 @@ import net.jini.lookup.DiscoveryAdmin;
 // com.sun.jini
 import com.sun.jini.outrigger.JavaSpaceAdmin;
 import com.sun.jini.outrigger.AdminIterator;
-import com.sun.jini.admin.DestroyAdmin;
 
-import com.sun.jini.qa.harness.Admin;
-import com.sun.jini.qa.harness.ActivatableServiceStarterAdmin;
 
 // com.sun.jini.qa
-import com.sun.jini.qa.harness.QATest;
+import com.sun.jini.qa.harness.QATestEnvironment;
 import com.sun.jini.qa.harness.TestException;
 import com.sun.jini.qa.harness.QAConfig;
-import com.sun.jini.test.share.DiscoveryAdminUtil;
+import com.sun.jini.qa.harness.Test;
 
 import java.util.logging.Level;
 
 import net.jini.config.Configuration;
 import net.jini.config.ConfigurationException;
 import net.jini.security.ProxyPreparer;
+import org.apache.river.api.security.CombinerSecurityManager;
 
 /**
- * Base class for spaces QA tests.  Provides convince functions for
+ * Base class for spaces QA tests.  Provides convenience functions for
  * logging failure, starting/finding and cleaning up the services under
  * test.  Also sets up a command line parser.
  * <p>
@@ -127,82 +122,91 @@ import net.jini.security.ProxyPreparer;
  * be used to let the test know if it should be testing the lookup
  * service or the JavaSpace.
  */
-public abstract class TestBase extends QATest {
-    DiscoveryAdmin admin = null;
+public abstract class TestBase extends QATestEnvironment {
+    volatile DiscoveryAdmin admin = null;
 
     /**
      * Holds instances to LRS proxy objects returned from StartService.
      */
-    private ArrayList startedServices = new ArrayList();
+    private final ArrayList startedServices = new ArrayList();//access using synchronized
 
     /** URL to find lookup, null if we are in standAlone mode */
-    protected LookupLocator locator = null;
+    protected volatile LookupLocator locator = null;
 
     /** Lookup groups to find lookup, null if we are in standAlone mode */
-    protected String groups[] = null;
+    protected volatile String groups[] = null;
 
     /**
      * Number of milliseconds to wait after cleaning up the services.
      */
-    protected long cleanupWait = 0;
+    protected volatile long cleanupWait = 0;
 
     /** True is we are in standalone mode */
-    protected boolean standAlone;
+    protected volatile boolean standAlone;
 
     /**
      * Flag that indicates we should try to scrub the services once we find them
      */
-    protected boolean scrub = false;
+    protected volatile boolean scrub = false;
 
     /** Flag that indicates we should not destroy on exit. */
-    protected boolean destroy = true;
+    protected volatile boolean destroy = true;
 
     /**
      * Class name to substitute for Administrable when looking/starting
      * services to test
      */
-    protected String administrableSubstitute = null;
+    protected volatile String administrableSubstitute = null;
 
     /**
      * Class name to substitute for JavaSpace when looking/starting
      * services to test
      */
-    protected String javaSpaceSubstitute = null;
+    protected volatile String javaSpaceSubstitute = null;
 
     /** List of leases to cancel during cleanup */
-    private List leaseList = new java.util.LinkedList();
+    private final List leaseList = new java.util.LinkedList();//access using synchronized
 
     /**
      * Set of services to test.  @see#specifyServices for details
+     * 
+     * Only updated while holding lock to startedServices.
      */
-    protected Object[] services;
+    protected volatile Object[] services;
 
     /**
      * True if we should be using lookup
      */
-    private boolean useLookup;
+    private volatile boolean useLookup;
 
     /**
      * If we kill a VM during the test the min time to wait before restart
      */
-    protected long minPostKillWait;
+    protected volatile long minPostKillWait;
 
     // Do we wait at the end
-    protected boolean waitAtEnd;
+    protected volatile boolean waitAtEnd;
 
     /**
      * the name of service for which these test are written
      */
     protected final String serviceName = "net.jini.lease.LeaseRenewalService";
 
-    public void setup(QAConfig config) throws Exception {
-        super.setup(config);
+    public Test construct(QAConfig config) throws Exception {
+        super.construct(config);
 
         // output the name of this test
         logger.log(Level.FINE, "Test Name = " + this.getClass().getName());
 
         // set security manager
-        System.setSecurityManager(new RMISecurityManager());
+        System.setSecurityManager(new CombinerSecurityManager());
+        return new Test(){
+
+            public void run() throws Exception {
+                // do nothing
+            }
+            
+        };
     }
 
     protected void specifyServices(Class[] serviceClasses)
@@ -213,19 +217,20 @@ public abstract class TestBase extends Q
 
             if (useLookup) {
                 ServiceRegistrar lookupProxy =
-		    manager.startLookupService(); // prepared by util
+		    getManager().startLookupService(); // prepared by util
 		// prepared by DiscoveryAdminUtil
                 admin = DiscoveryAdminUtil.getDiscoveryAdmin(lookupProxy);
             }
 
             // Setup services
-            for (int i = 0; i < serviceClasses.length; i++) {
-                logger.log(Level.FINE, "Starting service #" + i + ": "
-                        + serviceClassNames[i]);
-                startedServices.add(manager.startService(serviceClassNames[i]));
+            synchronized (startedServices){
+                for (int i = 0; i < serviceClasses.length; i++) {
+                    logger.log(Level.FINE, "Starting service #" + i + ": "
+                            + serviceClassNames[i]);
+                    startedServices.add(getManager().startService(serviceClassNames[i]));
+                }
+                services = startedServices.toArray(new Object[startedServices.size()]);
             }
-            services = startedServices.toArray(new Object[] {});
-
             if (scrub) {
                 for (int i = 0; i < services.length; i++) {
                     if (services[i] instanceof JavaSpace) {
@@ -235,7 +240,7 @@ public abstract class TestBase extends Q
             }
         } catch (Exception ex) {
             ex.printStackTrace();
-            throw new TestException("Exception has been catched in"
+            throw new TestException("Exception has been caught in"
                     + " specifyServices: " + ex.getMessage());
         }
     }
@@ -321,7 +326,7 @@ public abstract class TestBase extends Q
     private long shutdownNoSleep(int index) throws Exception {
         Object o = services[index];
         try {
-	    if (!manager.killVM(o)) {
+	    if (!getManager().killVM(o)) {
 		logger.log(Level.SEVERE, "Could not call killVM for service " + o);
             } else {
 		// get delay in seconds
@@ -533,7 +538,11 @@ public abstract class TestBase extends Q
      * destroyed.  This will set its entry in the services array to null
      */
     protected void serviceDestroyed(int index) {
-        services[index] = null;
+        synchronized (startedServices){ //to avoid interleved write.
+            Object [] serv = services;
+            serv[index] = null;
+            services = serv; //guarantees change to volatile array is visible to other threads.
+        }
     }
 
     protected void parse() throws Exception {

Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/TestParticipantImpl.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/TestParticipantImpl.java?rev=1427655&r1=1427654&r2=1427655&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/TestParticipantImpl.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/TestParticipantImpl.java Wed Jan  2 05:20:52 2013
@@ -22,7 +22,7 @@ import com.sun.jini.mahalo.*;
 import net.jini.core.transaction.*;
 import net.jini.core.transaction.server.*;
 
-import com.sun.jini.qa.harness.QATest;
+import com.sun.jini.qa.harness.QATestEnvironment;
 import com.sun.jini.qa.harness.QAConfig;
 
 import net.jini.config.Configuration;

Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/TesterTransactionManager.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/TesterTransactionManager.java?rev=1427655&r1=1427654&r2=1427655&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/TesterTransactionManager.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/TesterTransactionManager.java Wed Jan  2 05:20:52 2013
@@ -43,7 +43,7 @@ import net.jini.config.Configuration;
 import net.jini.config.ConfigurationException;
 import net.jini.security.TrustVerifier;
 import net.jini.security.proxytrust.ProxyTrust;
-import com.sun.jini.qa.harness.QATest;
+import com.sun.jini.qa.harness.QATestEnvironment;
 import com.sun.jini.qa.harness.QAConfig;
 
 /**

Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/TxnManagerTest.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/TxnManagerTest.java?rev=1427655&r1=1427654&r2=1427655&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/TxnManagerTest.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/TxnManagerTest.java Wed Jan  2 05:20:52 2013
@@ -32,12 +32,13 @@ import java.io.*;
 import java.rmi.*;
 
 import com.sun.jini.qa.harness.QAConfig;
+import com.sun.jini.qa.harness.Test;
 import com.sun.jini.qa.harness.TestException;
 
 /**
  */
 public abstract class TxnManagerTest extends TestBase
-    implements TransactionConstants, TxnManagerTestOpcodes
+    implements TransactionConstants, TxnManagerTestOpcodes, Test
 {
     protected static final boolean DEBUG = true;
 
@@ -52,9 +53,10 @@ public abstract class TxnManagerTest ext
 	mgrs[0]= (TransactionManager)services[0]; // prepared by specifyServices
     }
 
-    public void setup(QAConfig config) throws Exception {
-        super.setup(config);
+    public Test construct(QAConfig config) throws Exception {
+        super.construct(config);
         super.parse();
+        return this;
     }
 
     /**

Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/CheckTrustEquivalence_Test.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/CheckTrustEquivalence_Test.java?rev=1427655&r1=1427654&r2=1427655&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/CheckTrustEquivalence_Test.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/CheckTrustEquivalence_Test.java Wed Jan  2 05:20:52 2013
@@ -20,7 +20,8 @@ package com.sun.jini.test.spec.activatio
 import java.util.logging.Level;
 import net.jini.activation.ActivatableInvocationHandler;
 import com.sun.jini.qa.harness.TestException;
-import com.sun.jini.qa.harness.QATest;
+import com.sun.jini.qa.harness.QATestEnvironment;
+import com.sun.jini.qa.harness.Test;
 import java.rmi.activation.ActivationID;
 import com.sun.jini.test.spec.activation.util.FakeActivationID;
 import com.sun.jini.test.spec.activation.util.RMCProxy;
@@ -68,7 +69,7 @@ import com.sun.jini.test.spec.activation
  *          verify the return value is true
  * </pre>
  */
-public class CheckTrustEquivalence_Test extends QATest {
+public class CheckTrustEquivalence_Test extends QATestEnvironment implements Test {
 
     /**
      * This method performs all actions mentioned in class description.

Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/CheckTrustEquivalence_UntrustedAIDTest.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/CheckTrustEquivalence_UntrustedAIDTest.java?rev=1427655&r1=1427654&r2=1427655&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/CheckTrustEquivalence_UntrustedAIDTest.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/CheckTrustEquivalence_UntrustedAIDTest.java Wed Jan  2 05:20:52 2013
@@ -19,7 +19,8 @@ package com.sun.jini.test.spec.activatio
 
 import java.util.logging.Level;
 import net.jini.activation.ActivatableInvocationHandler;
-import com.sun.jini.qa.harness.QATest;
+import com.sun.jini.qa.harness.QATestEnvironment;
+import com.sun.jini.qa.harness.Test;
 import java.rmi.activation.ActivationID;
 import com.sun.jini.test.spec.activation.util.FakeActivationID;
 import com.sun.jini.test.spec.activation.util.RMCProxy;
@@ -50,7 +51,7 @@ import com.sun.jini.test.spec.activation
  *          verify the return value is false
  * </pre>
  */
-public class CheckTrustEquivalence_UntrustedAIDTest extends QATest {
+public class CheckTrustEquivalence_UntrustedAIDTest extends QATestEnvironment implements Test {
 
     /**
      * This method performs all actions mentioned in class description.

Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Constructor_AccessorTest.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Constructor_AccessorTest.java?rev=1427655&r1=1427654&r2=1427655&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Constructor_AccessorTest.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Constructor_AccessorTest.java Wed Jan  2 05:20:52 2013
@@ -19,8 +19,9 @@ package com.sun.jini.test.spec.activatio
 
 import java.util.logging.Level;
 import com.sun.jini.qa.harness.TestException;
-import com.sun.jini.qa.harness.QATest;
+import com.sun.jini.qa.harness.QATestEnvironment;
 import com.sun.jini.qa.harness.QAConfig;
+import com.sun.jini.qa.harness.Test;
 import java.rmi.activation.ActivationID;
 import net.jini.activation.ActivatableInvocationHandler;
 import com.sun.jini.test.spec.activation.util.MethodSetProxy;
@@ -55,7 +56,7 @@ import com.sun.jini.test.spec.activation
  *          verify NullPointerException is thrown
  * </pre>
  */
-public class Constructor_AccessorTest extends QATest {
+public class Constructor_AccessorTest extends QATestEnvironment implements Test {
 
     /**
      * This method performs all actions mentioned in class description.

Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/GetActivationID_CallTest.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/GetActivationID_CallTest.java?rev=1427655&r1=1427654&r2=1427655&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/GetActivationID_CallTest.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/GetActivationID_CallTest.java Wed Jan  2 05:20:52 2013
@@ -18,7 +18,8 @@
 package com.sun.jini.test.spec.activation.activatableinvocationhandler;
 
 import java.util.logging.Level;
-import com.sun.jini.qa.harness.QATest;
+import com.sun.jini.qa.harness.QATestEnvironment;
+import com.sun.jini.qa.harness.Test;
 import com.sun.jini.qa.harness.TestException;
 import java.rmi.activation.ActivationID;
 import net.jini.activation.ActivatableInvocationHandler;
@@ -46,7 +47,7 @@ import com.sun.jini.test.spec.activation
  *       3) assert the returned value is the same as used in constructor
  * </pre>
  */
-public class GetActivationID_CallTest extends QATest {
+public class GetActivationID_CallTest extends QATestEnvironment implements Test {
 
     /**
      * This method performs all actions mentioned in class description.

Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/GetCurrentProxy_CallTest.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/GetCurrentProxy_CallTest.java?rev=1427655&r1=1427654&r2=1427655&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/GetCurrentProxy_CallTest.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/GetCurrentProxy_CallTest.java Wed Jan  2 05:20:52 2013
@@ -24,7 +24,8 @@ import java.util.logging.Logger;
 import java.util.logging.Level;
 import java.rmi.Remote;
 import java.rmi.activation.ActivationID;
-import com.sun.jini.qa.harness.QATest;
+import com.sun.jini.qa.harness.QATestEnvironment;
+import com.sun.jini.qa.harness.Test;
 import net.jini.activation.ActivatableInvocationHandler;
 import com.sun.jini.test.spec.activation.util.FakeActivationID;
 import com.sun.jini.test.spec.activation.util.RemoteMethodSetInterface;
@@ -70,7 +71,7 @@ import com.sun.jini.test.spec.activation
  *       17) assert the returned value is equal to MethodSetProxy object
  * </pre>
  */
-public class GetCurrentProxy_CallTest extends QATest {
+public class GetCurrentProxy_CallTest extends QATestEnvironment implements Test {
 
     /**
      * This method performs all actions mentioned in class description.

Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Invoke_MethodsNoActivationTest.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Invoke_MethodsNoActivationTest.java?rev=1427655&r1=1427654&r2=1427655&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Invoke_MethodsNoActivationTest.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Invoke_MethodsNoActivationTest.java Wed Jan  2 05:20:52 2013
@@ -23,7 +23,8 @@ import net.jini.jeri.BasicInvocationHand
 import net.jini.jeri.ObjectEndpoint;
 import net.jini.jeri.OutboundRequest;
 import com.sun.jini.qa.harness.TestException;
-import com.sun.jini.qa.harness.QATest;
+import com.sun.jini.qa.harness.QATestEnvironment;
+import com.sun.jini.qa.harness.Test;
 import java.lang.reflect.Proxy;
 import java.lang.reflect.InvocationHandler;
 import java.util.Arrays;
@@ -58,7 +59,7 @@ import com.sun.jini.test.spec.activation
  *        d) assert the return value is returned
  * </pre>
  */
-public class Invoke_MethodsNoActivationTest extends QATest {
+public class Invoke_MethodsNoActivationTest extends QATestEnvironment implements Test {
 
     /**
      * This method performs all actions mentioned in class description.

Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Invoke_MethodsWithActivationTest.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Invoke_MethodsWithActivationTest.java?rev=1427655&r1=1427654&r2=1427655&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Invoke_MethodsWithActivationTest.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Invoke_MethodsWithActivationTest.java Wed Jan  2 05:20:52 2013
@@ -23,7 +23,8 @@ import net.jini.jeri.BasicInvocationHand
 import net.jini.jeri.ObjectEndpoint;
 import net.jini.jeri.OutboundRequest;
 import com.sun.jini.qa.harness.TestException;
-import com.sun.jini.qa.harness.QATest;
+import com.sun.jini.qa.harness.QATestEnvironment;
+import com.sun.jini.qa.harness.Test;
 import java.rmi.Remote;
 import java.rmi.activation.ActivationID;
 import java.lang.reflect.Proxy;
@@ -64,7 +65,7 @@ import com.sun.jini.test.spec.activation
  *        d) assert the valid value is returned
  * </pre>
  */
-public class Invoke_MethodsWithActivationTest extends QATest {
+public class Invoke_MethodsWithActivationTest extends QATestEnvironment implements Test {
 
     /**
      * This method performs all actions mentioned in class description.

Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Invoke_ObjectMethodsTest.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Invoke_ObjectMethodsTest.java?rev=1427655&r1=1427654&r2=1427655&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Invoke_ObjectMethodsTest.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Invoke_ObjectMethodsTest.java Wed Jan  2 05:20:52 2013
@@ -23,7 +23,8 @@ import java.util.logging.Level;
 import java.lang.reflect.Proxy;
 import net.jini.activation.ActivatableInvocationHandler;
 import com.sun.jini.qa.harness.TestException;
-import com.sun.jini.qa.harness.QATest;
+import com.sun.jini.qa.harness.QATestEnvironment;
+import com.sun.jini.qa.harness.Test;
 import com.sun.jini.test.spec.activation.util.FakeActivationID;
 
 
@@ -85,7 +86,7 @@ import com.sun.jini.test.spec.activation
  *         steps 8 to 10 are for ActivatableInvocationHandler
  * </pre>
  */
-public class Invoke_ObjectMethodsTest extends QATest {
+public class Invoke_ObjectMethodsTest extends QATestEnvironment implements Test {
 
 
     interface FakeInterface1 {

Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Invoke_WithExceptionNoActivationTest.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Invoke_WithExceptionNoActivationTest.java?rev=1427655&r1=1427654&r2=1427655&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Invoke_WithExceptionNoActivationTest.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/activation/activatableinvocationhandler/Invoke_WithExceptionNoActivationTest.java Wed Jan  2 05:20:52 2013
@@ -23,7 +23,8 @@ import net.jini.jeri.BasicInvocationHand
 import net.jini.jeri.ObjectEndpoint;
 import net.jini.jeri.OutboundRequest;
 import com.sun.jini.qa.harness.TestException;
-import com.sun.jini.qa.harness.QATest;
+import com.sun.jini.qa.harness.QATestEnvironment;
+import com.sun.jini.qa.harness.Test;
 import java.lang.reflect.Proxy;
 import java.lang.reflect.InvocationHandler;
 import java.util.Arrays;
@@ -76,7 +77,7 @@ import com.sun.jini.test.spec.activation
  *     6) assert the tested exception is thrown
  * </pre>
  */
-public class Invoke_WithExceptionNoActivationTest extends QATest {
+public class Invoke_WithExceptionNoActivationTest extends QATestEnvironment implements Test {
     Throwable[] cases = { 
               new ArrayIndexOutOfBoundsException(),
               new AssertionError(),