/** * 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..."); }
/** * Get a list of "other" vms, along with stop modes. The "other" vms are any vms other than the * currently executing vm. The stop mode for each VM is chosen from util.StopStartPrms.stopMode. * * @param numVMsToTarget The number of VMs to target for a stop/start. * @param clientMatchStr A string the must be contained in the client name to be included in the * vms to target, or null. * @throws TestException if there aren't numToTarget VMs available. * @returns Object[0] - a List of ClientVmInfos. Object[1] - a List of stop modes. Object[2] - a * List of vms eligible but not chosen. */ public static Object[] getOtherVMs(int numToTarget, String clientMatchStr) { Log.getLogWriter().info("Choosing " + numToTarget + " vms (other than this one)"); // get the VMs; vmList and stopModeList are parallel lists ArrayList vmList = new ArrayList(); ArrayList stopModeList = new ArrayList(); int myVmID = RemoteTestModule.getMyVmid(); // get VMs that contain the clientMatchStr List vmInfoList = getAllVMs(); vmInfoList = getMatchVMs(vmInfoList, clientMatchStr); // now all vms in vmInfoList match the clientMatchStr do { if (vmInfoList.size() == 0) { throw new TestException( "Unable to find " + numToTarget + " vms to stop with client match string " + clientMatchStr + "; either a test problem or add StopStartVMs.StopStart_initTask to the test"); } // add a VmId to the list of vms to stop int randInt = TestConfig.tab().getRandGen().nextInt(0, vmInfoList.size() - 1); ClientVmInfo info = (ClientVmInfo) (vmInfoList.get(randInt)); if (info.getVmid().intValue() != myVmID) { // info is not the current VM vmList.add(info); // choose a stopMode String choice = TestConfig.tab().stringAt(StopStartPrms.stopModes); stopModeList.add(choice); } vmInfoList.remove(randInt); } while (vmList.size() < numToTarget); return new Object[] {vmList, stopModeList, vmInfoList}; }
/** * Check event counters in the ControllerBB shared map. For example, if baseKey is * ControllerBB.NumForcedDiscEventsKey and vmList is a list containing vmId 2, and expectedCount * is 1, then the event count of key with base NumForcedDiscEvents plus vmId 2 is expected to be * 1, and any other key found in the map that is prefixed by baseKey should have value be 0. * Throws an exception if the conditions are not satisfied. * * @param baseKey The base string of the key to check (the prefix to the vm id) * @param vmList The vms (ClientVmInfo) for the baseKey should have a value of expectedCount. * @param expectedCount The expected value of any baseKeys that refer to the given vmIds, * otherwise the expectedCount is 0. */ public static void checkEventCounters(String baseKey, List vmList, int expectedCount) { Map aMap = ControllerBB.getBB().getSharedMap().getMap(); Iterator it = aMap.keySet().iterator(); while (it.hasNext()) { String key = (String) (it.next()); if (key.startsWith(baseKey)) { // found a key prefixed by baseKey int value = ((Integer) (aMap.get(key))).intValue(); // value for the key boolean foundInVmIdList = false; for (int i = 0; i < vmList.size(); i++) { int vmId = ((Integer) ((ClientVmInfo) (vmList.get(i))).getVmid()).intValue(); if (key.endsWith("_" + vmId)) { // found a baseKey with a vmid in the vmList foundInVmIdList = true; if (value != expectedCount) { throw new TestException( "Expected value for BB key " + key + " to be " + expectedCount + " but it is " + value); } } } if (!foundInVmIdList) { // this key's value should be 0 if (value != 0) { throw new TestException( "Expected value for BB key " + key + " to be 0 but it is " + value); } } } } }
/** 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)); } } }
/** * Concurrently stops a List of Vms, then restart them. Does not wait for the restart to complete * before returning. This allows the caller to carry out operations concurrent with the stop and * start activity, then wait for the restart to complete using {@link * #joinStopStartThreads(List,List)}. * * <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 then restart. * @param stopModeList A parallel list of stop modes (Strings). * @return threadList The threads created to stop the VMs. */ public static List stopStartAsync(List targetVmList, List stopModeList) { if (targetVmList.size() != stopModeList.size()) { throw new TestException( "Expected targetVmList " + targetVmList + " and stopModeList " + stopModeList + " to be parallel lists of the same size, but they have different sizes"); } Log.getLogWriter() .info( "In stopStartVMs, vms to stop: " + targetVmList + ", corresponding stop modes: " + stopModeList); // 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)); } } // stop all vms in targetVms list List threadList = new ArrayList(); for (int i = 0; i < targetVmList.size(); i++) { ClientVmInfo targetVm = (ClientVmInfo) (targetVmList.get(i)); int stopMode = ClientVmMgr.toStopMode((String) (stopModeList.get(i))); Thread aThread = new StopStartVMs(targetVm, stopMode); aThread = new HydraSubthread(aThread); threadList.add(aThread); aThread.start(); } return threadList; }
/** * Return a List of all other vms except for one along with a parallel stop mode list, and also * return the one vm not in the list. * * @return [0] (List<ClientVmInfo>)A List of ClientVmInfo instances; this includes all vms except * the current vm and except for one other vm. [1] (List<String>) A parallel List to [0] * containing stop modes. [2] (ClientVMInfo) The ClientVmInfo instance of the one vm excluded * from [0] (other than this vm) [3] (String) The stop mode for [2] [4] (List<ClientVmInfo>) A * List of ClientVmInfo instances for all vms except this one. [5] (List<String>) A parallel * List to [4] of stop modes. */ public static Object[] getOtherVMsDivided(String[] excludedClientNames) { Vector<Integer> otherVmIDs = ClientVmMgr.getOtherClientVmids(); List<ClientVmInfo> allOtherVMs = new ArrayList(); List<String> stopModeList = new ArrayList(); for (int i = 0; i < otherVmIDs.size(); i++) { ClientVmInfo info = new ClientVmInfo(otherVmIDs.get(i)); ClientVmInfo infoFromBB = (ClientVmInfo) StopStartBB.getBB().getSharedMap().get(VmInfoKey + otherVmIDs.get(i)); if (infoFromBB != null) { info = infoFromBB; } String clientName = info.getClientName(); if (clientName == null) { allOtherVMs.add(info); stopModeList.add(TestConfig.tab().stringAt(StopStartPrms.stopModes)); } else { boolean inExcludedNames = false; for (String excludeName : excludedClientNames) { if (clientName.indexOf(excludeName) >= 0) inExcludedNames = true; break; } if (!inExcludedNames) { allOtherVMs.add(info); stopModeList.add(TestConfig.tab().stringAt(StopStartPrms.stopModes)); } } } List<ClientVmInfo> allOtherVMsExceptOne = allOtherVMs.subList(0, allOtherVMs.size() - 1); List<String> stopModesExceptOne = stopModeList.subList(0, stopModeList.size() - 1); ClientVmInfo remainingVM = allOtherVMs.get(allOtherVMs.size() - 1); String remainingStopMode = stopModeList.get(stopModeList.size() - 1); return new Object[] { allOtherVMsExceptOne, stopModesExceptOne, remainingVM, remainingStopMode, allOtherVMs, stopModeList }; }
/** * Return a List of all other vms except for one along with a parallel stop mode list, and also * return the one vm not in the list. * * @return [0] (List<ClientVmInfo>)A List of ClientVmInfo instances; this includes all vms except * the current vm and except for one other vm. [1] (List<String>) A parallel List to [0] * containing stop modes. [2] (ClientVMInfo) The ClientVmInfo instance of the one vm excluded * from [0] (other than this vm) [3] (String) The stop mode for [2] [4] (List<ClientVmInfo>) A * List of ClientVmInfo instances for all vms except this one. [5] (List<String>) A parallel * List to [4] of stop modes. */ public static Object[] getOtherVMsDivided() { Vector<Integer> otherVmIDs = ClientVmMgr.getOtherClientVmids(); List<ClientVmInfo> allOtherVMs = new ArrayList(); List<String> stopModeList = new ArrayList(); for (int i = 0; i < otherVmIDs.size(); i++) { ClientVmInfo info = new ClientVmInfo(otherVmIDs.get(i)); allOtherVMs.add(info); stopModeList.add(TestConfig.tab().stringAt(StopStartPrms.stopModes)); } List<ClientVmInfo> allOtherVMsExceptOne = allOtherVMs.subList(0, allOtherVMs.size() - 1); List<String> stopModesExceptOne = stopModeList.subList(0, stopModeList.size() - 1); ClientVmInfo remainingVM = allOtherVMs.get(allOtherVMs.size() - 1); String remainingStopMode = stopModeList.get(stopModeList.size() - 1); return new Object[] { allOtherVMsExceptOne, stopModesExceptOne, remainingVM, remainingStopMode, allOtherVMs, stopModeList }; }
/** * Get the vms whose client names contain matchStr * * @param vmInfoList A List of ClientVmInfo instances. * @param matchStr The string to check for in the client names. * @returns A List of ClientVmInfos whose clientName contains matchStr. */ public static List getMatchVMs(List vmInfoList, String matchStr) { List returnList = new ArrayList(); for (int i = 0; i < vmInfoList.size(); i++) { Object anObj = vmInfoList.get(i); if (anObj instanceof ClientVmInfo) { ClientVmInfo info = (ClientVmInfo) (anObj); if (info.getClientName().indexOf(matchStr) >= 0) { // its a match returnList.add(info); } } } return returnList; }
/** * Get a list of "other" vms, along with stop modes. The "other" vms are any vms other than the * currently executing vm. The stop mode for each VM is chosen from util.StopStartPrms.stopMode. * * @param numVMsToTarget The number of VMs to target for a stop/start. * @param clientExcludeStr Any vm name that contains this string as a substring is excluded from * consideration. * @throws TestException if there aren't numToTarget VMs available. * @returns Object[0] - a List of ClientVmInfos. Object[1] - a List of stop modes. Object[2] - a * List of vms eligible but not chosen. */ public static Object[] getOtherVMsWithExclude(int numToTarget, String clientExcludeStr) { Log.getLogWriter().info("Choosing " + numToTarget + " vms (other than this one)"); // get the VMs; vmList and stopModeList are parallel lists ArrayList vmList = new ArrayList(); ArrayList stopModeList = new ArrayList(); int myVmID = RemoteTestModule.getMyVmid(); // put numToTarget in vmList List vmInfoList = getAllVMs(); do { if (vmInfoList.size() == 0) { throw new TestException( "Unable to find " + numToTarget + " vms to stop with client exclude string " + clientExcludeStr + "; either a test problem or add StopStartVMs.StopStart_initTask to the test"); } // add a VmId to the list of vms to stop int randInt = TestConfig.tab().getRandGen().nextInt(0, vmInfoList.size() - 1); Object anObj = vmInfoList.get(randInt); if (anObj instanceof ClientVmInfo) { ClientVmInfo info = (ClientVmInfo) (anObj); if (info.getVmid().intValue() != myVmID) { // info is not the current VM if ((clientExcludeStr != null) && (info.getClientName().indexOf(clientExcludeStr) >= 0)) { // exclude this vm } else { vmList.add(info); // choose a stopMode String choice = TestConfig.tab().stringAt(StopStartPrms.stopModes); stopModeList.add(choice); } } } vmInfoList.remove(randInt); } while (vmList.size() < numToTarget); return new Object[] {vmList, stopModeList, vmInfoList}; }
/** * Asynchronously start the given vms and return a List of threads that spawned the start. This * allows the caller to carry out operations concurrent with the start activity, then wait for the * start to complete using {@link #joinStopStartThreads(List,List)}. * * @param targetVmList A list of hydra.ClientVmInfos to start. * @return threadList The threads created to start the VMs. */ public static List startAsync(List targetVmList) { Log.getLogWriter().info("In stopStartVMs, vms to start: " + targetVmList); // start all vms in targetVms list List threadList = new ArrayList(); for (int i = 0; i < targetVmList.size(); i++) { ClientVmInfo targetVm = (ClientVmInfo) (targetVmList.get(i)); Thread aThread = new StopStartVMs(targetVm, 0, false, true); aThread = new HydraSubthread(aThread); threadList.add(aThread); aThread.start(); } return threadList; }
/** * Verify the result of the CQs registered for this VM. Query results from * executeWithInitialResults are combined with subsequent cq events to form the final result. */ protected void verifyQueryResultsCombine() { Log.getLogWriter().info("In verifyQueryResultsCombine"); Iterator it = queryMap.keySet().iterator(); int count = 0; while (it.hasNext()) { count++; String cqName = (String) (it.next()); Log.getLogWriter() .info("Verifying query " + count + " out of " + queryMap.size() + " with name " + cqName); CqQuery cq = qService.getCq(cqName); String queryStr = cq.getQueryString(); String readableQueryStr = CQTest.getReadableQueryString(queryStr); // combine the initial selectResults with history of events CQHistory history = CQHistoryListener.getCQHistory(cqName); Map combinedMap = history.getCombinedResults(); List combinedList = new ArrayList(combinedMap.values()); List expectedResults = CQTestInstance.getExpectedResults(queryStr); List missingInCombined = new ArrayList(expectedResults); List unexpectedInCombined = new ArrayList(combinedList); unexpectedInCombined.removeAll(expectedResults); missingInCombined.removeAll(combinedList); // prepare error Strings StringBuffer aStr = new StringBuffer(); if (unexpectedInCombined.size() > 0) { String tmpStr = getLocationString(unexpectedInCombined, expectedResults, history) + "\n" + "Found the following " + unexpectedInCombined.size() + " unexpected elements in combined results for cq " + cqName + ", " + readableQueryStr + ": " + QueryObject.toStringFull(unexpectedInCombined); Log.getLogWriter().info(tmpStr); aStr.append(tmpStr); } if (missingInCombined.size() > 0) { String tmpStr = getLocationString(missingInCombined, expectedResults, history) + "\n" + "The following " + missingInCombined.size() + " elements were missing from combined results for cq " + cqName + ", " + readableQueryStr + ": " + QueryObject.toStringFull(missingInCombined); Log.getLogWriter().info(tmpStr); aStr.append(tmpStr); } if (aStr.length() > 0) { throw new TestException( "Probably bug 38065: For cq " + cqName + ", " + readableQueryStr + "\n" + aStr.toString()); } } Log.getLogWriter().info("Done verifying " + count + " queries"); }
/** * Given a List of QueryObjects known to be inconsistent as determined by validation, log where * the suspect objects are found by checking for it in 1) the expected List 2) the CQ history of * events 3) the select results 4) the localRegion * * @param inconsistencies A List of suspect QueryObjects to check in each location. * @param expected The expected List of objects for a query. * @param history The CQHistory for the query * @returns */ private String getLocationString(List inconsistencies, List expected, CQHistory history) { StringBuffer aStr = new StringBuffer(); for (int i = 0; i < inconsistencies.size(); i++) { QueryObject suspect = (QueryObject) (inconsistencies.get(i)); // check the local region boolean found = false; Iterator it = aRegion.keySet().iterator(); while (it.hasNext()) { Object key = it.next(); Region.Entry entry = aRegion.getEntry(key); QueryObject qo = (QueryObject) (entry.getValue()); if ((qo != null) && (qo.equals(suspect))) { found = true; aStr.append( qo.toStringAbbreviated() + " was found in " + aRegion.getFullPath() + " at key " + key + "\n"); } } if (!found) { aStr.append( suspect.toStringAbbreviated() + " was NOT found in " + aRegion.getFullPath() + "\n"); } // seach for all occurrences in expected list found = false; it = expected.iterator(); while (it.hasNext()) { QueryObject qo = (QueryObject) (it.next()); if (qo.equals(suspect)) { found = true; aStr.append(qo.toStringAbbreviated() + " was found in expected results\n"); } } if (!found) { aStr.append(suspect.toStringAbbreviated() + " was NOT found in expected results\n"); } // seach for all occurrences in selectResults SelectResults selResults = history.getSelectResults(); found = false; it = selResults.iterator(); while (it.hasNext()) { QueryObject qo = (QueryObject) (it.next()); if (qo.equals(suspect)) { found = true; aStr.append(qo.toStringAbbreviated() + " was found in SelectResults\n"); } } if (!found) { aStr.append(suspect.toStringAbbreviated() + " was NOT found in SelectResults\n"); } // seach for all occurrences in history found = false; List eventList = history.getEvents(); for (int j = 0; j < eventList.size(); j++) { CqEvent event = (CqEvent) (eventList.get(j)); QueryObject qo = (QueryObject) (event.getNewValue()); if ((qo != null) && (qo.equals(suspect))) { found = true; aStr.append( qo.toStringAbbreviated() + " was found in event history as new value " + event + "\n"); } } if (!found) { aStr.append(suspect.toStringAbbreviated() + " was NOT found in CqEvent history\n"); } } return aStr.toString(); }
/** * 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); }