/** * Do a get on a key in region REGION_NAME. Keys to get are specified in keyIntervals. * * @return true if all keys to have get performaed have been completed. */ protected boolean get() { SharedCounters sc = CQUtilBB.getBB().getSharedCounters(); long nextKey = sc.incrementAndRead(CQUtilBB.LASTKEY_GET); if (!keyIntervals.keyInRange(KeyIntervals.GET, nextKey)) { Log.getLogWriter().info("All gets completed; returning from get"); return true; } Object key = NameFactory.getObjectNameForCounter(nextKey); Log.getLogWriter().info("Getting " + key); try { Object existingValue = aRegion.get(key); Log.getLogWriter() .info( "Done getting " + key + ", num remaining: " + (keyIntervals.getLastKey(KeyIntervals.GET) - nextKey)); if (existingValue == null) throw new TestException("Get of key " + key + " returned unexpected " + existingValue); } catch (TimeoutException e) { throw new TestException(TestHelper.getStackTrace(e)); } catch (CacheLoaderException e) { throw new TestException(TestHelper.getStackTrace(e)); } return (nextKey >= keyIntervals.getLastKey(KeyIntervals.GET)); }
/** * Invalidate a key in region REGION_NAME. The keys to invalidate are specified in keyIntervals. * * @return true if all keys to be invalidated have been completed. */ protected boolean invalidate() { SharedCounters sc = CQUtilBB.getBB().getSharedCounters(); long nextKey = sc.incrementAndRead(CQUtilBB.LASTKEY_INVALIDATE); if (!keyIntervals.keyInRange(KeyIntervals.INVALIDATE, nextKey)) { Log.getLogWriter().info("All existing keys invalidated; returning from invalidate"); return true; } Object key = NameFactory.getObjectNameForCounter(nextKey); Log.getLogWriter().info("Invalidating " + key); checkContainsValueForKey(key, true, "before invalidate"); try { aRegion.invalidate(key); Log.getLogWriter() .info( "Done invalidating " + key + ", num remaining: " + (keyIntervals.getLastKey(KeyIntervals.INVALIDATE) - nextKey)); } catch (TimeoutException e) { throw new TestException(TestHelper.getStackTrace(e)); } catch (EntryNotFoundException e) { throw new TestException(TestHelper.getStackTrace(e)); } return (nextKey >= keyIntervals.getLastKey(KeyIntervals.INVALIDATE)); }
/** * Destroy a key in region REGION_NAME. The keys to destroy are specified in keyIntervals. * * @return true if all keys to be destroyed have been completed. */ protected boolean destroy() { SharedCounters sc = CQUtilBB.getBB().getSharedCounters(); long nextKey = sc.incrementAndRead(CQUtilBB.LASTKEY_DESTROY); if (!keyIntervals.keyInRange(KeyIntervals.DESTROY, nextKey)) { Log.getLogWriter().info("All destroys completed; returning from destroy"); return true; } Object key = NameFactory.getObjectNameForCounter(nextKey); Log.getLogWriter().info("Destroying " + key); checkContainsValueForKey(key, true, "before destroy"); try { aRegion.destroy(key); Log.getLogWriter() .info( "Done Destroying " + key + ", num remaining: " + (keyIntervals.getLastKey(KeyIntervals.DESTROY) - nextKey)); } catch (CacheWriterException e) { throw new TestException(TestHelper.getStackTrace(e)); } catch (TimeoutException e) { throw new TestException(TestHelper.getStackTrace(e)); } catch (EntryNotFoundException e) { throw new TestException(TestHelper.getStackTrace(e)); } return (nextKey >= keyIntervals.getLastKey(KeyIntervals.DESTROY)); }
/** * Run method for this thread: if this thread is set to stop, then stop a VM and wait for it to * stop. If this thread is set to start then start a VM and wait for it to start. Any errors are * placed in the blackboard errStr. */ public void run() { try { Log.getLogWriter().info("Started " + getName()); try { if (stop) { ClientVmMgr.stop( "Test is synchronously stopping " + targetVm + " with " + ClientVmMgr.toStopModeString(stopMode), stopMode, ClientVmMgr.ON_DEMAND, targetVm); } VMotionUtil.doVMotion(targetVm); if (start) { ClientVmMgr.start("Test is synchronously starting " + targetVm, targetVm); } } catch (hydra.ClientVmNotFoundException e) { Log.getLogWriter() .info("Caught in thread " + getName() + ":" + TestHelper.getStackTrace(e)); StopStartBB.getBB().getSharedMap().put(StopStartBB.errKey, TestHelper.getStackTrace(e)); } } catch (Throwable e) { Log.getLogWriter().info("Caught in thread " + getName() + ":" + TestHelper.getStackTrace(e)); StopStartBB.getBB().getSharedMap().put(StopStartBB.errKey, TestHelper.getStackTrace(e)); } Log.getLogWriter().info(getName() + " terminating"); }
/** Start all cqs running for this VM, and create a CQHistory instance for each CQ. */ private void startCQsWithHistory() { initializeQueryService(); CqAttributesFactory cqFac = new CqAttributesFactory(); cqFac.addCqListener(new CQHistoryListener()); cqFac.addCqListener(new CQGatherListener()); CqAttributes cqAttr = cqFac.create(); Iterator it = queryMap.keySet().iterator(); while (it.hasNext()) { String queryName = (String) (it.next()); String query = (String) (queryMap.get(queryName)); try { CqQuery cq = qService.newCq(queryName, query, cqAttr); CQHistory history = new CQHistory(cq.getName()); CQHistoryListener.recordHistory(history); Log.getLogWriter() .info( "Creating CQ with name " + queryName + ": " + query + ", cq attributes: " + cqAttr); Log.getLogWriter().info("Calling executeWithInitialResults on " + cq); CqResults rs = cq.executeWithInitialResults(); SelectResults sr = CQUtil.getSelectResults(rs); if (sr == null) { throw new TestException( "For cq " + cq + " with name " + cq.getName() + " executeWithInitialResults returned " + sr); } Log.getLogWriter() .info( "Done calling executeWithInitializResults on " + cq + " with name " + queryName + ", select results size is " + sr.size()); history.setSelectResults(sr); logNumOps(); // log the select results List srList = sr.asList(); StringBuffer aStr = new StringBuffer(); aStr.append("SelectResults returned from " + queryName + " is\n"); for (int i = 0; i < srList.size(); i++) { aStr.append(srList.get(i) + "\n"); } Log.getLogWriter().info(aStr.toString()); } catch (CqExistsException e) { throw new TestException(TestHelper.getStackTrace(e)); } catch (RegionNotFoundException e) { throw new TestException(TestHelper.getStackTrace(e)); } catch (CqException e) { throw new TestException(TestHelper.getStackTrace(e)); } } }
/** * Do operations on the REGION_NAME's keys using keyIntervals to specify which keys get which * operations. This will return when all operations in all intervals have completed. * * @param availableOps - Bits which are true correspond to the operations that should be executed. */ public void doOps(BitSet availableOps) { boolean useTransactions = getInitialImage.InitImagePrms.useTransactions(); while (availableOps.cardinality() != 0) { int whichOp = getOp(availableOps, operations.length); boolean doneWithOps = false; if (useTransactions) { TxHelper.begin(); } switch (whichOp) { case ADD_NEW_KEY: doneWithOps = addNewKey(); break; case INVALIDATE: doneWithOps = invalidate(); break; case DESTROY: doneWithOps = destroy(); break; case UPDATE_EXISTING_KEY: doneWithOps = updateExistingKey(); break; case GET: doneWithOps = get(); break; case LOCAL_INVALIDATE: doneWithOps = localInvalidate(); break; case LOCAL_DESTROY: doneWithOps = localDestroy(); break; default: { throw new TestException("Unknown operation " + whichOp); } } if (useTransactions) { try { TxHelper.commit(); } catch (CommitConflictException e) { // currently not expecting any conflicts ... throw new TestException( "Unexpected CommitConflictException " + TestHelper.getStackTrace(e)); } } if (doneWithOps) { Log.getLogWriter().info("Done with operation " + whichOp); availableOps.clear(whichOp); } if (sleepBetweenOps) { Log.getLogWriter().info("Sleeping between ops for " + SLEEP_BETWEEN_OPS_MILLIS + " millis"); MasterController.sleepForMs(SLEEP_BETWEEN_OPS_MILLIS); } } }
/** * Waits for a List of threads concurrently stopping and starting Vms to finish, as returned by * {@link #stopStartAsync(List,List)}. Resets the niceKill blackboard entry for each vm is set to * false. * * @param targetVmList A list of hydra.ClientVmInfos to stop then restart. * @param threadList A parallel list of threads on whom to wait. */ public static void joinStopStart(List targetVmList, List threadList) { Log.getLogWriter().info("Joining stop/start threads..."); // wait for all threads to complete the stop and start for (int i = 0; i < threadList.size(); i++) { HydraSubthread aThread = (HydraSubthread) (threadList.get(i)); try { aThread.join(); } catch (InterruptedException e) { throw new TestException(TestHelper.getStackTrace(e)); } Object err = StopStartBB.getBB().getSharedMap().get(StopStartBB.errKey); if (err != null) { throw new TestException(err.toString()); } } // reset the blackboard entries for (int i = 0; i < targetVmList.size(); i++) { ClientVmInfo targetVm = (ClientVmInfo) (targetVmList.get(i)); StopStartBB.getBB() .getSharedMap() .put(StopStartVMs.NiceKillInProgress + targetVm.getVmid(), new Boolean(false)); } Log.getLogWriter().info("Done joining stop/start threads..."); }
public void reduce(GFKey key, Iterable<PEIWritable> values, Context context) throws IOException, InterruptedException { // For a particular key ... process all records and output what we would have expected in this // concKnownKeys test // Note that we either // 1. do a single create // 2. create + update // 3. create + destroy // look at all ops ... and output either // 1. create // 2. create (with value from update) // 3. do nothing (overall result is destroy, so do not create the entry in the gemfire // validation region String keyStr = (String) key.getKey(); ValueHolder updateValue = null; ValueHolder createValue = null; boolean destroyed = false; System.out.println("KnownKeysMRv2.reduce() invoked with " + keyStr); for (PEIWritable value : values) { PersistedEventImpl event = value.getEvent(); Operation op = event.getOperation(); ValueHolder vh = null; if (op.isDestroy()) { destroyed = true; } else { try { vh = (ValueHolder) event.getDeserializedValue(); } catch (ClassNotFoundException e) { System.out.println( "KnownKeysMRv2.map() caught " + e + " : " + TestHelper.getStackTrace(e)); } if (op.isUpdate()) { updateValue = vh; } else { createValue = vh; } } System.out.println( "KnownKeysMRv2.reduce() record: " + op.toString() + ": key = " + keyStr + " and op " + op.toString()); } if (!destroyed) { if (updateValue != null) { context.write(key.getKey(), updateValue); } else { context.write(key.getKey(), createValue); } } }
// Identity mapper (log and write out processed key/value pairs, the value is the // PersistedEventImpl) public void map(GFKey key, PersistedEventImpl value, Context context) throws IOException, InterruptedException { String keyStr = (String) key.getKey(); Operation op = value.getOperation(); ValueHolder entryValue = null; System.out.println("map method invoked with " + keyStr + " " + op.toString()); try { entryValue = (ValueHolder) value.getDeserializedValue(); } catch (ClassNotFoundException e) { System.out.println("KnownKeysMRv2.map() caught " + e + " : " + TestHelper.getStackTrace(e)); } context.write(key, new PEIWritable(value)); }
/** * Create a region with the given region description name. * * @param regDescriptName The name of a region description. */ protected void initializeRegion(String regDescriptName) { CacheHelper.createCache("cache1"); String key = VmIDStr + RemoteTestModule.getMyVmid(); String xmlFile = key + ".xml"; try { CacheHelper.generateCacheXmlFile("cache1", regDescriptName, xmlFile); } catch (HydraRuntimeException e) { if (e.toString().indexOf("Cache XML file was already created") >= 0) { // this can occur when reinitializing after a stop-start because // the cache xml file is written during the first init tasks } else { throw new TestException(TestHelper.getStackTrace(e)); } } aRegion = RegionHelper.createRegion(regDescriptName); }
protected void initializeQueryService() { try { String usingPool = TestConfig.tab().stringAt(CQUtilPrms.QueryServiceUsingPool, "false"); boolean queryServiceUsingPool = Boolean.valueOf(usingPool).booleanValue(); if (queryServiceUsingPool) { Pool pool = PoolHelper.createPool(CQUtilPrms.getQueryServicePoolName()); qService = pool.getQueryService(); Log.getLogWriter() .info("Initializing QueryService using Pool. PoolName: " + pool.getName()); } else { qService = CacheHelper.getCache().getQueryService(); Log.getLogWriter().info("Initializing QueryService using Cache."); } } catch (Exception e) { throw new TestException(TestHelper.getStackTrace(e)); } }
/** * Creates a new key/value in the given region by creating a new key within the range and a random * value. * * @param aRegion The region to create the new key in. * @param exists Not used in this overridden method; this test wants to use unique keys even on * creates, so we don't do anything different here based on the value of exists. * @return An instance of Operation describing the create operation. */ @Override public Operation createEntry(Region aRegion, boolean exists) { int lower = ((Integer) (lowerKeyRange.get())).intValue(); int upper = ((Integer) (upperKeyRange.get())).intValue(); long keyIndex = TestConfig.tab().getRandGen().nextInt(lower, upper); long startKeyIndex = keyIndex; Object key = NameFactory.getObjectNameForCounter(keyIndex); boolean containsKey = aRegion.containsKey(key); while (containsKey) { // looking for a key that does not exist keyIndex++; // go to the next key if (keyIndex > upper) keyIndex = lower; if (keyIndex == startKeyIndex) { // considered all keys return null; } key = NameFactory.getObjectNameForCounter(keyIndex); containsKey = aRegion.containsKey(key); } BaseValueHolder vh = new ValueHolder(key, randomValues, new Integer(modValInitializer++)); try { Log.getLogWriter() .info( "createEntryKeyRange: putting key " + key + ", object " + vh.toString() + " in region " + aRegion.getFullPath()); aRegion.put(key, vh); Log.getLogWriter() .info( "createEntryKeyRange: done putting key " + key + ", object " + vh.toString() + " in region " + aRegion.getFullPath()); } catch (Exception e) { throw new TestException(TestHelper.getStackTrace(e)); } return new Operation(aRegion.getFullPath(), key, Operation.ENTRY_CREATE, null, vh.modVal); }
/** * Verify the contents of the region, taking into account the keys that were destroyed, * invalidated, etc (as specified in keyIntervals) Throw an error of any problems are detected. * This must be called repeatedly by the same thread until StopSchedulingTaskOnClientOrder is * thrown. */ public void verifyRegionContents() { final long LOG_INTERVAL_MILLIS = 10000; // we already completed this check once; we can't do it again without reinitializing the // verify state variables if (verifyRegionContentsCompleted) { throw new TestException( "Test configuration problem; already verified region contents, " + "cannot call this task again without resetting batch variables"); } // iterate keys long lastLogTime = System.currentTimeMillis(); long minTaskGranularitySec = TestConfig.tab().longAt(TestHelperPrms.minTaskGranularitySec); long minTaskGranularityMS = minTaskGranularitySec * TestHelper.SEC_MILLI_FACTOR; long startTime = System.currentTimeMillis(); long size = aRegion.size(); boolean first = true; int numKeysToCheck = keyIntervals.getNumKeys() + numNewKeys; while (verifyRegionContentsIndex < numKeysToCheck) { verifyRegionContentsIndex++; if (first) { Log.getLogWriter() .info( "In verifyRegionContents, region has " + size + " keys; starting verify at verifyRegionContentsIndex " + verifyRegionContentsIndex + "; verifying key names with indexes through (and including) " + numKeysToCheck); first = false; } // check region size the first time through the loop to avoid it being called // multiple times when this is batched if (verifyRegionContentsIndex == 1) { if (totalNumKeys != size) { String tmpStr = "Expected region size to be " + totalNumKeys + ", but it is size " + size; Log.getLogWriter().info(tmpStr); verifyRegionContentsErrStr.append(tmpStr + "\n"); } } Object key = NameFactory.getObjectNameForCounter(verifyRegionContentsIndex); try { if (((verifyRegionContentsIndex >= keyIntervals.getFirstKey(KeyIntervals.NONE)) && (verifyRegionContentsIndex <= keyIntervals.getLastKey(KeyIntervals.NONE))) || ((verifyRegionContentsIndex >= keyIntervals.getFirstKey(KeyIntervals.GET)) && (verifyRegionContentsIndex <= keyIntervals.getLastKey(KeyIntervals.GET)))) { // this key was untouched after its creation checkContainsKey(key, true, "key was untouched"); checkContainsValueForKey(key, true, "key was untouched"); Object value = aRegion.get(key); checkValue(key, value); } else if ((verifyRegionContentsIndex >= keyIntervals.getFirstKey(KeyIntervals.INVALIDATE)) && (verifyRegionContentsIndex <= keyIntervals.getLastKey(KeyIntervals.INVALIDATE))) { checkContainsKey(key, true, "key was invalidated"); checkContainsValueForKey(key, false, "key was invalidated"); } else if ((verifyRegionContentsIndex >= keyIntervals.getFirstKey(KeyIntervals.LOCAL_INVALIDATE)) && (verifyRegionContentsIndex <= keyIntervals.getLastKey(KeyIntervals.LOCAL_INVALIDATE))) { // this key was locally invalidated checkContainsKey(key, true, "key was locally invalidated"); checkContainsValueForKey(key, true, "key was locally invalidated"); Object value = aRegion.get(key); checkValue(key, value); } else if ((verifyRegionContentsIndex >= keyIntervals.getFirstKey(KeyIntervals.DESTROY)) && (verifyRegionContentsIndex <= keyIntervals.getLastKey(KeyIntervals.DESTROY))) { // this key was destroyed checkContainsKey(key, false, "key was destroyed"); checkContainsValueForKey(key, false, "key was destroyed"); } else if ((verifyRegionContentsIndex >= keyIntervals.getFirstKey(KeyIntervals.LOCAL_DESTROY)) && (verifyRegionContentsIndex <= keyIntervals.getLastKey(KeyIntervals.LOCAL_DESTROY))) { // this key was locally destroyed checkContainsKey(key, true, "key was locally destroyed"); checkContainsValueForKey(key, true, "key was locally destroyed"); Object value = aRegion.get(key); checkValue(key, value); } else if ((verifyRegionContentsIndex >= keyIntervals.getFirstKey(KeyIntervals.UPDATE_EXISTING_KEY)) && (verifyRegionContentsIndex <= keyIntervals.getLastKey(KeyIntervals.UPDATE_EXISTING_KEY))) { // this key was updated checkContainsKey(key, true, "key was updated"); checkContainsValueForKey(key, true, "key was updated"); Object value = aRegion.get(key); checkUpdatedValue(key, value); } else if (verifyRegionContentsIndex > keyIntervals.getNumKeys()) { // key was newly added checkContainsKey(key, true, "key was new"); checkContainsValueForKey(key, true, "key was new"); Object value = aRegion.get(key); checkValue(key, value); } } catch (TestException e) { Log.getLogWriter().info(TestHelper.getStackTrace(e)); verifyRegionContentsErrStr.append(e.getMessage() + "\n"); } if (System.currentTimeMillis() - lastLogTime > LOG_INTERVAL_MILLIS) { Log.getLogWriter() .info("Verified key " + verifyRegionContentsIndex + " out of " + totalNumKeys); lastLogTime = System.currentTimeMillis(); } if (System.currentTimeMillis() - startTime >= minTaskGranularityMS) { Log.getLogWriter() .info( "In HydraTask_verifyRegionContents, returning before completing verify " + "because of task granularity (this task must be batched to complete); last key verified is " + key); return; // task is batched; we are done with this batch } } verifyRegionContentsCompleted = true; if (verifyRegionContentsErrStr.length() > 0) { throw new TestException(verifyRegionContentsErrStr.toString()); } String aStr = "In HydraTask_verifyRegionContents, verified " + verifyRegionContentsIndex + " keys/values"; Log.getLogWriter().info(aStr); throw new StopSchedulingTaskOnClientOrder(aStr); }
/** * Invokes AdminDistributedSystem.shutDownAllMembers() which disconnects all members but leaves * the vms up (because hydra threads remain) including the possibility of this vm being * disconnected, then this actually stops those vms (except this vm if it was targeted in the * shutDownAllMembers...this vm will remain up but disconnect). Stopped vms are stopped with * ON_DEMAND restart. This returns when the vms disconnected by shutDownAllMembers() (other than * this one) are all stopped . * * @param adminDS The admin distributed system instance to use to call shutdownAllMembers. * @param stopModes The stop modes to choose from. * @return An Array [0] List of {@link ClientVmInfo} instances describing the VMs that were * stopped. [1] Set, the return from shutdownAllMembers() * @throws AdminException if the shutDownAllMembers call throws this exception. */ public static Object[] shutDownAllMembers( AdminDistributedSystem adminDS, List<String> stopModes) { if (adminDS == null) { throw new HydraRuntimeException("AdminDistributedSystem cannot be null"); } // Invoke shutDownAllMembers Log.getLogWriter().info("AdminDS " + adminDS + " is shutting down all members..."); Set<DistributedMember> memberSet; try { long startTime = System.currentTimeMillis(); memberSet = adminDS.shutDownAllMembers(); long duration = System.currentTimeMillis() - startTime; Log.getLogWriter() .info( "AdminDS " + adminDS + " shut down (disconnected) the following members " + "(vms remain up): " + memberSet + "; shutDownAll duration " + duration + "ms"); } catch (AdminException e1) { throw new TestException(TestHelper.getStackTrace(e1)); } // Now actually stop the vms. // First get the ClientVmInfos for the members that shutDownAllMembers // disconnected. List<ClientVmInfo> allClientInfos = new ArrayList(); // all members that were shutdown List<ClientVmInfo> allOtherClientInfos = new ArrayList(); // all members that were shutdown except this member ClientVmInfo thisClientInfo = null; // this member, or will remain null if this member was not shutdown List<String> stopModesToUse = new ArrayList(); for (DistributedMember aMember : memberSet) { Integer vmId = null; try { vmId = new Integer(RemoteTestModule.Master.getVmid(aMember.getHost(), aMember.getProcessId())); } catch (java.rmi.RemoteException e) { throw new HydraRuntimeException("Unable to get vmID for " + aMember + ": " + e); } ClientVmInfo infoFromBB = (ClientVmInfo) StopStartBB.getBB().getSharedMap().get("StopStartVMInfo_for_vmid_" + vmId); String clientName = null; if (infoFromBB != null) { clientName = infoFromBB.getClientName(); } ClientVmInfo info = new ClientVmInfo(vmId, clientName, null); allClientInfos.add(info); if (vmId == RemoteTestModule.getMyVmid()) { // shutdownAll disconnected this vm thisClientInfo = info; } else { // aMember is not the current vm allOtherClientInfos.add(info); } stopModesToUse.add( stopModes.get(TestConfig.tab().getRandGen().nextInt(0, stopModes.size() - 1))); } // now actually stop the vms; if this vm is included, do it last Object[] returnArr = new Object[2]; if (thisClientInfo == null) { // shutDownAllMembers did not disconnect this vm // we can just stop all of them now and this vm lives on StopStartVMs.stopVMs(allClientInfos, stopModesToUse); // restart is ON_DEMAND returnArr[0] = allClientInfos; } else { // this vm was disconnected by shutDownAllMembers // first shutdown all other members except this one StopStartVMs.stopVMs(allOtherClientInfos, stopModesToUse.subList(0, stopModesToUse.size())); returnArr[0] = allOtherClientInfos; } returnArr[1] = memberSet; return returnArr; }
/** * Concurrently stop and/or start a List of Vms. Wait for the operations to complete before * returning. * * <p>Side effects: For any VM which is performing a NICE_KILL because of this call, it is marked * as such in the StopStartBB (blackboard). The blackboard will contain a key prefixed with * util.StopStartVMs.NiceKillInProgress and appended to with its VmId. The value of this key is * the true. * * <p>This blackboard entry is for the convenience of the caller, and it is up to the caller to * look for it or not. When a VM undergoes a NICE_KILL, the VM closes the cache and disconnects * from the distributed system. Any threads in that VM doing work can get exceptions during the * close and/or disconnect step. This blackboard entry is useful for those threads to allow * exceptions when they know an exception is possible. * * @param targetVmList A list of hydra.ClientVmInfos to stop and/or start. * @param stopModeList A parallel list of stop modes (Strings), if doStop is true. * @param doStop True if we want to stop the targetVmList, false if not. * @param doStart True if we want to start the targetVmList, false if not. */ private static void stopStartVMs( List targetVmList, List stopModeList, boolean doStop, boolean doStart) { Log.getLogWriter() .info( "In stopStartVMs, vms to " + getAction(doStop, doStart) + ": " + targetVmList + ", corresponding stop modes: " + stopModeList); if (doStop) { // mark in the blackboard any vms that will undergo a NICE_KILL for (int i = 0; i < stopModeList.size(); i++) { String stopMode = (String) (stopModeList.get(i)); if (ClientVmMgr.toStopMode(stopMode) == ClientVmMgr.NICE_KILL) { // write nice kills to the blackboard so the killed vm may, if it chooses, handle any // exceptions that are underway. StopStartBB.getBB() .getSharedMap() .put( NiceKillInProgress + ((ClientVmInfo) targetVmList.get(i)).getVmid(), new Boolean(true)); } } } // process the vms in targetVms list List threadList = new ArrayList(); for (int i = 0; i < targetVmList.size(); i++) { ClientVmInfo targetVm = (ClientVmInfo) (targetVmList.get(i)); int stopMode = 0; if (doStop) { stopMode = ClientVmMgr.toStopMode((String) (stopModeList.get(i))); } StringBuffer aStr = new StringBuffer(); Thread aThread = new StopStartVMs(targetVm, stopMode, doStop, doStart); aThread = new HydraSubthread(aThread); threadList.add(aThread); aThread.start(); } // wait for all threads to complete their actions for (int i = 0; i < threadList.size(); i++) { Thread aThread = (Thread) (threadList.get(i)); try { aThread.join(); } catch (InterruptedException e) { throw new TestException(TestHelper.getStackTrace(e)); } } String err = (String) (StopStartBB.getBB().getSharedMap().get(StopStartBB.errKey)); if (err != null) { throw new TestException(err); } // reset the blackboard entries if (doStop) { for (int i = 0; i < targetVmList.size(); i++) { ClientVmInfo targetVm = (ClientVmInfo) (targetVmList.get(i)); StopStartBB.getBB() .getSharedMap() .put(StopStartVMs.NiceKillInProgress + targetVm.getVmid(), new Boolean(false)); } } Log.getLogWriter() .info("In stopStartVMs, done with " + getAction(doStop, doStart) + ": " + targetVmList); }