| /******************************************************************************* |
| * Copyright (c) 2000, 2015 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.debug.jdi.tests; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.ListIterator; |
| import java.util.Map; |
| import java.util.Vector; |
| |
| import junit.framework.Test; |
| |
| import com.sun.jdi.ClassNotLoadedException; |
| import com.sun.jdi.ClassType; |
| import com.sun.jdi.Field; |
| import com.sun.jdi.IncompatibleThreadStateException; |
| import com.sun.jdi.IntegerValue; |
| import com.sun.jdi.InvalidTypeException; |
| import com.sun.jdi.InvocationException; |
| import com.sun.jdi.Method; |
| import com.sun.jdi.ObjectReference; |
| import com.sun.jdi.ReferenceType; |
| import com.sun.jdi.StringReference; |
| import com.sun.jdi.ThreadReference; |
| import com.sun.jdi.Value; |
| import com.sun.jdi.event.ThreadStartEvent; |
| |
| /** |
| * Tests for JDI com.sun.jdi.ObjectReference |
| * and JDWP Object command set. |
| */ |
| public class ObjectReferenceTest extends AbstractJDITest { |
| |
| private ObjectReference fObject; |
| |
| /** |
| * Creates a new test. |
| */ |
| public ObjectReferenceTest() { |
| super(); |
| } |
| /** |
| * Init the fields that are used by this test only. |
| */ |
| @Override |
| public void localSetUp() { |
| // Make sure the object is in expected state (eg. it has not entered a monitor) |
| waitUntilReady(); |
| |
| // Get static field "fObject" |
| fObject = getObjectReference(); |
| } |
| /** |
| * Make sure the test leaves the VM in the same state it found it. |
| */ |
| @Override |
| public void localTearDown() { |
| // The test has resumed and suspended the Test Thread. Make sure this |
| // thread is suspended at the right location |
| waitUntilReady(); |
| } |
| /** |
| * Run all tests and output to standard output. |
| * @param args |
| */ |
| public static void main(java.lang.String[] args) { |
| new ObjectReferenceTest().runSuite(args); |
| } |
| /** |
| * Gets the name of the test case. |
| * @see junit.framework.TestCase#getName() |
| */ |
| @Override |
| public String getName() { |
| return "com.sun.jdi.ObjectReference"; |
| } |
| /** |
| * Returns all tests |
| */ |
| @Override |
| protected Test suite() { |
| JDITestSuite suite = (JDITestSuite) super.suite(); |
| Vector<?> testNames = getAllMatchingTests("testLast"); |
| Iterator<?> iterator = testNames.iterator(); |
| while (iterator.hasNext()) { |
| String name = (String) iterator.next(); |
| suite.addTest(new JDITestCase(this, name)); |
| } |
| return suite; |
| } |
| /** |
| * Test JDI disableCollection(). enableCollection() and isCollected(). |
| */ |
| public void testJDIDisableEnableCollection() { |
| assertTrue("1", !fObject.isCollected()); |
| fObject.disableCollection(); |
| fObject.enableCollection(); |
| } |
| /** |
| * Test JDI entryCount(). |
| */ |
| public void testJDIEntryCount() { |
| if (fVM.canGetMonitorInfo()) { |
| // Ensure we're in a good state |
| fVM.resume(); |
| waitUntilReady(); |
| |
| try { |
| assertEquals("1", 1, fObject.entryCount()); |
| } catch (IncompatibleThreadStateException e) { |
| assertTrue("2", false); |
| } |
| } |
| } |
| /** |
| * Test JDI equals() and hashCode(). |
| */ |
| public void testJDIEquality() { |
| assertTrue("1", fObject.equals(fObject)); |
| ObjectReference other = getThread(); |
| assertTrue("2", !fObject.equals(other)); |
| assertTrue("3", !fObject.equals(new Object())); |
| assertTrue("4", !fObject.equals(null)); |
| assertTrue("5", fObject.hashCode() != other.hashCode()); |
| } |
| /** |
| * Test JDI getValue(Field), getValues(List) and setValue(Field,Value) |
| * and JDWP 'Object - Get Fields Values' and 'Object - Set Fields Values'. |
| */ |
| public void testJDIGetSetValues() { |
| // setup |
| ReferenceType type = fObject.referenceType(); |
| List<?> fields = type.fields(); |
| ListIterator<?> iterator = fields.listIterator(); |
| List<Field> instanceFields = new LinkedList<>(); |
| while (iterator.hasNext()) { |
| Field field = (Field) iterator.next(); |
| if (!field.isStatic()) |
| instanceFields.add(field); |
| } |
| Field field = instanceFields.get(4); |
| assertEquals("1", "fChar", field.name()); |
| |
| // getValues(List) |
| Map<?, ?> values = fObject.getValues(instanceFields); |
| assertTrue("2", values.size() == 7); |
| Value value = (Value) values.get(field); |
| assertEquals("3", value, fVM.mirrorOf('a')); |
| |
| // setValue(Field,Value) |
| Value newValue = fVM.mirrorOf('b'); |
| try { |
| fObject.setValue(field, newValue); |
| } catch (ClassNotLoadedException e) { |
| assertTrue("4.1", false); |
| } catch (InvalidTypeException e) { |
| assertTrue("4.2", false); |
| } |
| |
| // getValue(Field) |
| assertEquals("5", fObject.getValue(field), newValue); |
| |
| // test set and get null value. |
| field = instanceFields.get(5); |
| |
| assertEquals("6", "fString2", field.name()); |
| try { |
| fObject.setValue(field, null); |
| } catch (ClassNotLoadedException e) { |
| assertTrue("7.1", false); |
| } catch (InvalidTypeException e) { |
| assertTrue("7.2", false); |
| } |
| |
| // getValue(Field) |
| assertEquals("8", fObject.getValue(field), null); |
| |
| // test get final value. |
| field = instanceFields.get(6); |
| assertEquals("9", "fString3", field.name()); |
| |
| // The value is null and should be because it's final |
| //assertEquals("10", fVM.mirrorOf("HEY"), fObject.getValue(field)); |
| |
| } |
| /** |
| * Test JDI invokeMethod. |
| */ |
| public void testJDIInvokeMethod() { |
| // Make sure the entire VM is not suspended before we start a new thread |
| // (otherwise this new thread will start suspended and we will never get the |
| // ThreadStart event) |
| fVM.resume(); |
| waitUntilReady(); |
| |
| ThreadStartEvent event = |
| (ThreadStartEvent) triggerAndWait(fVM |
| .eventRequestManager() |
| .createThreadStartRequest(), |
| "ThreadStartEvent", |
| false); |
| ThreadReference thread = event.thread(); |
| ClassType ct = (ClassType) fObject.referenceType(); |
| Method inv = |
| ct.concreteMethodByName("invoke3", "(Ljava/lang/String;Ljava/lang/Object;)I"); |
| List<StringReference> args = new ArrayList<>(); |
| args.add(fVM.mirrorOf("888")); |
| args.add(null); |
| Exception oops = null; |
| Value val = null; |
| try { |
| val = fObject.invokeMethod(thread, inv, args, 0); |
| } catch (ClassNotLoadedException exc) { |
| oops = exc; |
| } catch (IncompatibleThreadStateException exc) { |
| oops = exc; |
| } catch (InvalidTypeException exc) { |
| oops = exc; |
| } catch (InvocationException exc) { |
| oops = exc; |
| } |
| assertTrue("1", oops == null); |
| assertEquals("2", val == null ? 0 : ((IntegerValue) val).value(), 888); |
| } |
| /** |
| * Test JDI invokeMethod - failure. |
| */ |
| public void testJDIInvokeMethodFail() { |
| // Make sure the entire VM is not suspended before we start a new thread |
| // (otherwise this new thread will start suspended and we will never get the |
| // ThreadStart event) |
| fVM.resume(); |
| waitUntilReady(); |
| |
| ThreadStartEvent event = |
| (ThreadStartEvent) triggerAndWait(fVM |
| .eventRequestManager() |
| .createThreadStartRequest(), |
| "ThreadStartEvent", |
| false); |
| ThreadReference thread = event.thread(); |
| ClassType ct = (ClassType) fObject.referenceType(); |
| Method inv = ct.concreteMethodByName("invoke4", "()J"); |
| Exception good = null, oops = null; |
| try { |
| fObject.invokeMethod(thread, inv, new ArrayList<Value>(), 0); |
| } catch (ClassNotLoadedException exc) { |
| oops = exc; |
| } catch (IncompatibleThreadStateException exc) { |
| oops = exc; |
| } catch (InvalidTypeException exc) { |
| oops = exc; |
| } catch (InvocationException exc) { |
| good = exc; |
| } |
| assertTrue("1", oops == null); |
| assertTrue("2", good != null); |
| } |
| /** |
| * Test JDI owningThread(). |
| */ |
| public void testJDIOwningThread() { |
| if (fVM.canGetMonitorInfo()) { |
| // Ensure we're in a good state |
| fVM.resume(); |
| waitUntilReady(); |
| |
| try { |
| assertEquals("1", getThread(), fObject.owningThread()); |
| } catch (IncompatibleThreadStateException e) { |
| assertTrue("2", false); |
| } |
| } |
| } |
| /** |
| * Test JDI referenceType() and JDWP 'Type - Get type'. |
| */ |
| public void testJDIReferenceType() { |
| ReferenceType type = fObject.referenceType(); |
| assertEquals("1", type.name(), "org.eclipse.debug.jdi.tests.program.MainClass"); |
| } |
| /** |
| * Test JDI uniqueID(). |
| */ |
| public void testJDIUniqueID() { |
| fObject.uniqueID(); |
| } |
| /** |
| * Test JDI waitingThreads(). |
| */ |
| public void testJDIWaitingThreads() { |
| if (fVM.canGetMonitorInfo()) { |
| try { |
| assertEquals("1", 0, fObject.waitingThreads().size()); |
| } catch (IncompatibleThreadStateException e) { |
| assertTrue("2", false); |
| } |
| } |
| } |
| } |