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: * InstrumentationTest.java
043: * JUnit based test
044: *
045: * Created on November 7, 2006, 2:14 PM
046: */
047: package org.netbeans.lib.profiler.tests.jfluid.perf;
048:
049: import junit.framework.*;
050: import org.netbeans.junit.NbPerformanceTest;
051: import org.netbeans.lib.profiler.ProfilerEngineSettings;
052: import org.netbeans.lib.profiler.client.ClientUtils;
053: import org.netbeans.lib.profiler.global.CommonConstants;
054: import org.netbeans.lib.profiler.global.ProfilingSessionStatus;
055: import org.netbeans.lib.profiler.instrumentation.Instrumentor;
056: import org.netbeans.lib.profiler.tests.jfluid.CommonProfilerTestCase;
057: import org.netbeans.lib.profiler.wireprotocol.InstrumentMethodGroupResponse;
058: import org.netbeans.lib.profiler.wireprotocol.RootClassLoadedCommand;
059: import java.io.BufferedInputStream;
060: import java.io.ByteArrayOutputStream;
061: import java.io.File;
062: import java.io.PrintStream;
063: import java.util.ArrayList;
064: import java.util.Enumeration;
065: import java.util.HashSet;
066: import java.util.jar.JarEntry;
067: import java.util.jar.JarFile;
068:
069: /**
070: *
071: * @author ehucka
072: */
073: public class InstrumentationTest extends CommonProfilerTestCase
074: implements NbPerformanceTest {
075: //~ Instance fields ----------------------------------------------------------------------------------------------------------
076:
077: ArrayList<NbPerformanceTest.PerformanceData> data = new ArrayList();
078: ProfilerEngineSettings settings;
079: String[] classNames;
080: byte[][] classesBytes;
081:
082: //~ Constructors -------------------------------------------------------------------------------------------------------------
083:
084: public InstrumentationTest(String testName) {
085: super (testName);
086: }
087:
088: //~ Methods ------------------------------------------------------------------------------------------------------------------
089:
090: public static Test suite() {
091: TestSuite suite = new TestSuite(
092: org.netbeans.lib.profiler.tests.jfluid.perf.InstrumentationTest.class);
093:
094: return suite;
095: }
096:
097: public NbPerformanceTest.PerformanceData[] getPerformanceData() {
098: return data.toArray(new NbPerformanceTest.PerformanceData[data
099: .size()]);
100: }
101:
102: public void reportPerformance(String name, long value, String unit) {
103: NbPerformanceTest.PerformanceData d = new NbPerformanceTest.PerformanceData();
104: d.name = name;
105: d.value = value;
106: d.unit = unit;
107: d.threshold = NbPerformanceTest.PerformanceData.NO_THRESHOLD;
108: data.add(d);
109: }
110:
111: public void testJ2SE() {
112: try {
113: String jarPath = "/perfdata/j2se-simple.jar";
114: File f = new File(getDataDir(), jarPath);
115: assertTrue("Instrumented jar file doesn't exist.", f
116: .exists());
117: initTest(f.getAbsolutePath());
118: startInstrumentationTest(f.getAbsolutePath());
119: } catch (Exception ex) {
120: ex.printStackTrace();
121: fail();
122: }
123: }
124:
125: public void testJaxb() {
126: try {
127: String jarPath = "/perfdata/jaxb-xjc.jar";
128: File f = new File(getDataDir(), jarPath);
129: assertTrue("Instrumented jar file doesn't exist.", f
130: .exists());
131: initTest(f.getAbsolutePath());
132: startInstrumentationTest(f.getAbsolutePath());
133: } catch (Exception ex) {
134: ex.printStackTrace();
135: fail();
136: }
137: }
138:
139: public void testJaxbNoGettersEmpties() {
140: try {
141: String jarPath = "/perfdata/jaxb-xjc.jar";
142: File f = new File(getDataDir(), jarPath);
143: assertTrue("Instrumented jar file doesn't exist.", f
144: .exists());
145: initTest(f.getAbsolutePath());
146: settings.setInstrumentGetterSetterMethods(false);
147: settings.setInstrumentEmptyMethods(false);
148: startInstrumentationTest(f.getAbsolutePath());
149: } catch (Exception ex) {
150: ex.printStackTrace();
151: fail();
152: }
153: }
154:
155: public void testSimple() {
156: try {
157: String jarPath = "/perfdata/oneclass.jar";
158: File f = new File(getDataDir(), jarPath);
159: assertTrue("Instrumented jar file doesn't exist.", f
160: .exists());
161: initTest(f.getAbsolutePath());
162: startInstrumentationTest(f.getAbsolutePath());
163: } catch (Exception ex) {
164: ex.printStackTrace();
165: fail();
166: }
167: }
168:
169: public void testSimpleNoEmpties() {
170: try {
171: String jarPath = "/perfdata/oneclass.jar";
172: File f = new File(getDataDir(), jarPath);
173: assertTrue("Instrumented jar file doesn't exist.", f
174: .exists());
175: initTest(f.getAbsolutePath());
176: settings.setInstrumentEmptyMethods(false);
177: startInstrumentationTest(f.getAbsolutePath());
178: } catch (Exception ex) {
179: ex.printStackTrace();
180: fail();
181: }
182: }
183:
184: public void testSimpleNoGetters() {
185: try {
186: String jarPath = "/perfdata/oneclass.jar";
187: File f = new File(getDataDir(), jarPath);
188: assertTrue("Instrumented jar file doesn't exist.", f
189: .exists());
190: initTest(f.getAbsolutePath());
191: settings.setInstrumentGetterSetterMethods(false);
192: startInstrumentationTest(f.getAbsolutePath());
193: } catch (Exception ex) {
194: ex.printStackTrace();
195: fail();
196: }
197: }
198:
199: protected void setClasses(String jarPath) throws Exception {
200: ArrayList<String> names = new ArrayList(16);
201: ArrayList<byte[]> bytes = new ArrayList(16);
202: JarFile file = new JarFile(jarPath);
203: Enumeration<JarEntry> entries = file.entries();
204: ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
205: int read = 0;
206: byte[] buffer = new byte[1024];
207:
208: while (entries.hasMoreElements()) {
209: JarEntry entry = entries.nextElement();
210:
211: if (entry.getName().endsWith(".class")) {
212: String nm = entry.getName();
213: nm = nm.substring(0, nm.lastIndexOf("."));
214: names.add(nm);
215:
216: BufferedInputStream bis = new BufferedInputStream(file
217: .getInputStream(entry));
218:
219: while ((read = bis.read(buffer)) > -1) {
220: bos.write(buffer, 0, read);
221: }
222:
223: bis.close();
224: bytes.add(bos.toByteArray());
225: bos.reset();
226: }
227: }
228:
229: classNames = names.toArray(new String[names.size()]);
230: classesBytes = bytes.toArray(new byte[bytes.size()][]);
231: }
232:
233: protected void setRootMethods(String jarFile) throws Exception {
234: JarFile file = new JarFile(jarFile);
235: HashSet<String> list = new HashSet(8);
236:
237: for (Enumeration<JarEntry> entries = file.entries(); entries
238: .hasMoreElements();) {
239: JarEntry entry = entries.nextElement();
240:
241: if (entry.getName().endsWith(".class")) {
242: String name = entry.getName();
243: int idx = name.lastIndexOf('/');
244: String packageName = (idx == -1) ? name : name
245: .substring(0, idx);
246: packageName = packageName.replace('/', '.');
247: list.add(packageName);
248: }
249: }
250:
251: ClientUtils.SourceCodeSelection[] ret = new ClientUtils.SourceCodeSelection[list
252: .size()];
253: String[] cls = list.toArray(new String[list.size()]);
254:
255: for (int i = 0; i < list.size(); i++) {
256: ret[i] = new ClientUtils.SourceCodeSelection(cls[i] + ".",
257: "", ""); //NOI18N
258: }
259:
260: settings.setInstrumentationRootMethods(ret);
261: }
262:
263: protected boolean checkBytes(String className, byte[] bytes) {
264: String clnm = className.replace(".", "/");
265: int clindex = -1;
266:
267: for (int i = 0; i < classNames.length; i++) {
268: if (classNames[i].equals(clnm)) {
269: clindex = i;
270:
271: break;
272: }
273: }
274:
275: if (clindex == -1) {
276: throw new IllegalStateException("Class " + className
277: + " has not original.");
278: }
279:
280: byte[] origbytes = classesBytes[clindex];
281:
282: if (origbytes.length != bytes.length) {
283: return false;
284: }
285:
286: for (int i = 0; i < bytes.length; i++) {
287: if (bytes[i] != origbytes[i]) {
288: return false;
289: }
290: }
291:
292: return true;
293: }
294:
295: protected ProfilerEngineSettings initTest(String pathToJar)
296: throws Exception {
297: settings = new ProfilerEngineSettings();
298: settings.setPortNo(5140);
299: settings.setSeparateConsole(false);
300: settings.setCPUProfilingType(CommonConstants.CPU_INSTR_FULL);
301: settings.setInstrScheme(CommonConstants.INSTRSCHEME_TOTAL);
302: settings.setInstrumentEmptyMethods(true);
303: settings.setInstrumentGetterSetterMethods(true);
304: settings.setInstrumentMethodInvoke(true);
305: settings.setInstrumentSpawnedThreads(true);
306: settings.setJVMArgs("");
307:
308: setRootMethods(pathToJar);
309:
310: setTargetVM(settings);
311: //setClassPath(settings);
312: setProfilerHome(settings);
313:
314: setStatus(STATUS_NONE);
315:
316: return settings;
317: }
318:
319: protected void startInstrumentationTest(String jarFile)
320: throws Exception {
321: ProfilingSessionStatus status = new ProfilingSessionStatus();
322: status.targetJDKVersionString = settings
323: .getTargetJDKVersionString();
324:
325: PrintStream oldOutStream = System.out;
326: PrintStream oldErrStream = System.err;
327: System.setOut(getLogStream());
328: System.setErr(getLogStream());
329:
330: Instrumentor instr = new Instrumentor(status, settings);
331: instr.setStatusInfoFromSourceCodeSelection(settings
332: .getInstrumentationRootMethods());
333: status.currentInstrType = CommonConstants.INSTR_RECURSIVE_FULL;
334:
335: setClasses(jarFile);
336:
337: int[] loadersIDs = new int[classNames.length];
338:
339: for (int i = 0; i < classNames.length; i++) {
340: loadersIDs[i] = 20;
341: }
342:
343: int[] parentloadersIDs = new int[classNames.length];
344:
345: for (int i = 0; i < classNames.length; i++) {
346: parentloadersIDs[i] = 0;
347: }
348:
349: RootClassLoadedCommand cmd = new RootClassLoadedCommand(
350: classNames, loadersIDs, classesBytes,
351: classNames.length, parentloadersIDs, null);
352: log("Start instrumenting ...");
353:
354: InstrumentMethodGroupResponse resp = null;
355: long time = System.currentTimeMillis();
356: resp = instr.createInitialInstrumentMethodGroupResponse(cmd);
357: time = System.currentTimeMillis() - time;
358: ref("Number of Classes: " + classNames.length);
359:
360: byte[][] clbytes = resp.getReplacementClassFileBytes();
361: ref("Instrumented Classes: " + resp.getBase().getNClasses());
362: ref("Instrumented Methods: " + resp.getBase().getNMethods());
363:
364: if (resp.getErrorMessage() != null) {
365: log("Error Message: " + resp.getErrorMessage());
366: }
367:
368: String[] clnames = resp.getMethodClasses();
369: byte[][] bts = resp.getReplacementClassFileBytes();
370: boolean comp = false;
371:
372: for (int i = 0; i < clnames.length; i++) {
373: if (checkBytes(clnames[i], bts[i])) {
374: log("Equals bytes: " + clnames[i]);
375: }
376: }
377:
378: System.setOut(oldOutStream);
379: System.setErr(oldErrStream);
380: reportPerformance(getName(), time, "ms");
381: }
382: }
|