001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: * The Original Software is NetBeans. The Initial Developer of the Original
026: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
027: * Microsystems, Inc. All Rights Reserved.
028: *
029: * If you wish your version of this file to be governed by only the CDDL
030: * or only the GPL Version 2, indicate your decision by adding
031: * "[Contributor] elects to include this software in this distribution
032: * under the [CDDL or GPL Version 2] license." If you do not indicate a
033: * single choice of license, a recipient has the option to distribute
034: * your version of this file under either the CDDL, the GPL Version 2 or
035: * to extend the choice of license to its licensees as provided above.
036: * However, if you add GPL Version 2 code and therefore, elected the GPL
037: * Version 2 license, then the option applies only if the new code is
038: * made subject to such option by the copyright holder.
039: */
040:
041: /*
042: * MonitorTestCase.java
043: *
044: * Created on July 19, 2005, 5:21 PM
045: *
046: * To change this template, choose Tools | Options and locate the template under
047: * the Source Creation and Management node. Right-click the template and choose
048: * Open. You can then make changes to the template in the Source Editor.
049: */
050: package org.netbeans.lib.profiler.tests.jfluid.monitor;
051:
052: import org.netbeans.lib.profiler.ProfilerEngineSettings;
053: import org.netbeans.lib.profiler.TargetAppRunner;
054: import org.netbeans.lib.profiler.client.MonitoredData;
055: import org.netbeans.lib.profiler.global.CommonConstants;
056: import org.netbeans.lib.profiler.results.monitor.VMTelemetryDataManager;
057: import org.netbeans.lib.profiler.results.threads.ThreadData;
058: import org.netbeans.lib.profiler.results.threads.ThreadsDataManager;
059: import org.netbeans.lib.profiler.tests.jfluid.*;
060: import org.netbeans.lib.profiler.tests.jfluid.utils.*;
061: import java.awt.Color;
062: import java.util.ArrayList;
063: import java.util.Arrays;
064: import java.util.Collections;
065: import java.util.HashMap;
066:
067: /**
068: *
069: * @author ehucka
070: */
071: public abstract class MonitorTestCase extends CommonProfilerTestCase {
072: //~ Static fields/initializers -----------------------------------------------------------------------------------------------
073:
074: static final byte ST_UNKNOWN = 1;
075: static final byte ST_ZOMBIE = 2;
076: static final byte ST_RUNNING = 4;
077: static final byte ST_SLEEPING = 8;
078: static final byte ST_MONITOR = 16;
079: static final byte ST_WAIT = 32;
080: static final int MONITOR_ONLY = 0;
081: static final int WITH_CPU = 1;
082: static final int WITH_MEMORY = 2;
083: static final int WITH_CODEREGION = 3;
084:
085: //~ Constructors -------------------------------------------------------------------------------------------------------------
086:
087: /**
088: * Creates a new instance of MonitorTestCase
089: */
090: public MonitorTestCase(String name) {
091: super (name);
092: }
093:
094: //~ Methods ------------------------------------------------------------------------------------------------------------------
095:
096: protected char getState(byte state) {
097: if (state == ST_UNKNOWN) {
098: return ('U');
099: } else if (state == ST_ZOMBIE) {
100: return ('Z');
101: } else if (state == ST_RUNNING) {
102: return ('R');
103: } else if (state == ST_SLEEPING) {
104: return ('S');
105: } else if (state == ST_MONITOR) {
106: return ('M');
107: } else if (state == ST_WAIT) {
108: return ('W');
109: }
110:
111: return '-';
112: }
113:
114: protected String getStates(byte[] states) {
115: StringBuffer sb = new StringBuffer(states.length);
116:
117: for (int i = 0; i < states.length; i++) {
118: sb.append(getState(states[i]));
119: }
120:
121: return sb.toString();
122: }
123:
124: protected void detectStates(byte[] states, byte[] detectStates) {
125: int detectionindex = 0;
126:
127: for (int i = 0; i < states.length; i++) {
128: if ((states[i] & detectStates[detectionindex]) == 0) {
129: detectionindex++;
130:
131: if ((detectionindex >= detectStates.length)
132: || ((states[i] & detectStates[detectionindex]) == 0)) {
133: log("\n*********NOT MATCHING STATES");
134: log(getStates(states));
135: log("Matching states: " + getStates(detectStates));
136: log("Wrong state " + getState(states[i])
137: + " index " + i);
138: assertTrue("States do not match with pattern",
139: false);
140: }
141: }
142: }
143: }
144:
145: protected ProfilerEngineSettings initMonitorTest(
146: String projectName, String className) {
147: //System.setProperty("org.netbeans.lib.profiler.wireprotocol.WireIO", "true");
148: ProfilerEngineSettings settings = initTest(projectName,
149: className, null);
150: //defaults
151: settings.setThreadCPUTimerOn(false);
152:
153: return settings;
154: }
155:
156: protected void logLongs(long[] longs, int count) {
157: double average = 0.0;
158: long max = 0;
159: long min = Long.MAX_VALUE;
160:
161: for (int i = 0; i < count; i++) {
162: average += longs[i];
163:
164: if (max < longs[i]) {
165: max = longs[i];
166: }
167:
168: if (min > longs[i]) {
169: min = longs[i];
170: }
171: }
172:
173: average /= count;
174: log("Average = " + average + " Max = " + max + " Min = " + min
175: + " Values = " + count);
176: }
177:
178: protected void startMonitorTest(ProfilerEngineSettings settings,
179: int times, long delay, String[] detects,
180: byte[][] detectstates, int profilingType) {
181: TargetAppRunner runner = new TargetAppRunner(settings,
182: new TestProfilerAppHandler(this ),
183: new TestProfilingPointsProcessor());
184: runner.addProfilingEventListener(Utils
185: .createProfilingListener(this ));
186:
187: try {
188: runner.readSavedCalibrationData();
189:
190: Process p = startTargetVM(runner);
191: assertNotNull("Target JVM is not started", p);
192: bindStreams(p);
193:
194: runner.connectToStartedVMAndStartTA();
195:
196: if (profilingType == WITH_CPU) {
197: runner
198: .getProfilerClient()
199: .initiateRecursiveCPUProfInstrumentation(
200: settings
201: .getInstrumentationRootMethods());
202: } else if (profilingType == WITH_MEMORY) {
203: runner.getProfilerClient()
204: .initiateMemoryProfInstrumentation(
205: CommonConstants.INSTR_OBJECT_LIVENESS);
206: } else if (profilingType == WITH_CODEREGION) {
207: runner
208: .getProfilerClient()
209: .initiateCodeRegionInstrumentation(
210: settings
211: .getInstrumentationRootMethods());
212: }
213: assert runner.targetAppIsRunning();
214: waitForStatus(STATUS_RUNNING);
215:
216: VMTelemetryDataManager dataManager = new VMTelemetryDataManager();
217: dataManager.setArrayBufferSize(10);
218:
219: ThreadsDataManager threadsManager = new ThreadsDataManager();
220:
221: //run monitoring - data are stored into states map
222: for (int cntr = 0; cntr < times; cntr++) {
223: Thread.sleep(delay);
224:
225: if (isStatus(STATUS_APP_FINISHED)) {
226: break;
227: }
228:
229: if (!runner.targetJVMIsAlive()) {
230: break;
231: }
232:
233: runner.getProfilerClient().forceObtainedResultsDump();
234:
235: MonitoredData data = runner.getProfilerClient()
236: .getMonitoredData();
237:
238: dataManager.processData(data);
239: threadsManager.processData(data);
240: }
241:
242: setStatus(STATUS_MEASURED);
243:
244: //detect stored data - sign defined state and OR them from all matching threads
245: HashMap threads = new HashMap(32);
246: HashMap timestamps = new HashMap(32);
247:
248: assertTrue("Threads manager has not data", threadsManager
249: .hasData());
250:
251: int statesNumber = 128;
252: long deltat = threadsManager.getEndTime()
253: - threadsManager.getStartTime();
254: double tick = (double) deltat / (double) statesNumber;
255: ArrayList names = new ArrayList();
256:
257: for (int i = 0; i < threadsManager.getThreadsCount(); i++) {
258: ThreadData td = threadsManager.getThreadData(i);
259:
260: if (!td.getName().equals("process reaper")
261: && !td.getName().equals("DestroyJavaVM")) { //disable system threads
262:
263: byte[] states = new byte[statesNumber];
264: String n = td.getName() + ", class: "
265: + td.getClassName();
266: byte state = ST_UNKNOWN;
267: long time = threadsManager.getStartTime();
268: int tdindex = 0;
269:
270: for (int j = 0; j < states.length; j++) {
271: if ((tdindex < td.size())
272: && (time >= td.getTimeStampAt(tdindex))) {
273: state = toBinState(td.getStateAt(tdindex));
274:
275: Color color = td
276: .getThreadStateColorAt(tdindex);
277: assertNotNull(
278: "Threads state color is null",
279: color);
280: tdindex++;
281: }
282:
283: states[j] = state;
284: time = (long) ((j * tick) + threadsManager
285: .getStartTime());
286: }
287:
288: td.clearStates();
289: assertTrue("Error in threadData.clearStates", (td
290: .size() == 0));
291: names.add(td.getName());
292: threads.put(n, states);
293: timestamps.put(n, new Long(td.getFirstTimeStamp()));
294: }
295: }
296:
297: String[] keys = (String[]) threads.keySet().toArray(
298: new String[threads.size()]);
299: Arrays.sort(keys);
300: Collections.sort(names);
301:
302: for (int i = 0; i < names.size(); i++) {
303: ref(names.get(i));
304: }
305:
306: boolean[] ret = null;
307: int maxindex = 0;
308:
309: for (int i = 0; i < keys.length; i++) {
310: byte[] sts = (byte[]) (threads.get(keys[i]));
311: log(keys[i]);
312: log(getStates(sts));
313:
314: for (int j = 0; j < detects.length; j++) {
315: if (keys[i].startsWith(detects[j])) {
316: detectStates(sts, detectstates[j]);
317: }
318: }
319: }
320:
321: assertEquals("Some threads are multiple - issue 68266",
322: names.size(), keys.length);
323: //log datas
324: log("\nDataManager item counts "
325: + dataManager.getItemCount());
326: log("Free Memory");
327: logLongs(dataManager.freeMemory, dataManager.getItemCount());
328: log("lastGCPauseInMS");
329: logLongs(dataManager.lastGCPauseInMS, dataManager
330: .getItemCount());
331: log("nSurvivingGenerations");
332: logLongs(dataManager.nSurvivingGenerations, dataManager
333: .getItemCount());
334: log("nSystemThreads");
335: logLongs(dataManager.nSystemThreads, dataManager
336: .getItemCount());
337: log("nTotalThreads");
338: logLongs(dataManager.nTotalThreads, dataManager
339: .getItemCount());
340: log("nUserThreads");
341: logLongs(dataManager.nUserThreads, dataManager
342: .getItemCount());
343: log("relativeGCTimeInPerMil");
344: logLongs(dataManager.relativeGCTimeInPerMil, dataManager
345: .getItemCount());
346: log("timeStamps");
347: logLongs(dataManager.timeStamps, dataManager.getItemCount());
348: log("totalMemory");
349: logLongs(dataManager.totalMemory, dataManager
350: .getItemCount());
351: log("usedMemory");
352: logLongs(dataManager.usedMemory, dataManager.getItemCount());
353: } catch (Exception ex) {
354: log(ex);
355: assertTrue("Exception thrown: " + ex.getMessage(), false);
356: } finally {
357: finalizeTest(runner);
358: }
359: }
360:
361: protected byte toBinState(byte state) {
362: if (state == CommonConstants.THREAD_STATUS_UNKNOWN) {
363: return ST_UNKNOWN;
364: } else if (state == CommonConstants.THREAD_STATUS_ZOMBIE) {
365: return ST_ZOMBIE;
366: } else if (state == CommonConstants.THREAD_STATUS_RUNNING) {
367: return ST_RUNNING;
368: } else if (state == CommonConstants.THREAD_STATUS_SLEEPING) {
369: return ST_SLEEPING;
370: } else if (state == CommonConstants.THREAD_STATUS_MONITOR) {
371: return ST_MONITOR;
372: } else if (state == CommonConstants.THREAD_STATUS_WAIT) {
373: return ST_WAIT;
374: }
375:
376: return 0;
377: }
378: }
|