diff options
author | eutarass | 2011-07-06 04:21:43 +0000 |
---|---|---|
committer | eutarass | 2011-07-06 04:21:43 +0000 |
commit | cd529d385d79a2ecc6b97a2bd110273c90835e8f (patch) | |
tree | a3e1946f812809c127e97bacadccde008568bf18 /plugins/org.eclipse.tm.tcf.debug | |
parent | a6c9682d4414a815f5f78df6b3f6539cfe3e0935 (diff) | |
download | org.eclipse.tcf-cd529d385d79a2ecc6b97a2bd110273c90835e8f.tar.gz org.eclipse.tcf-cd529d385d79a2ecc6b97a2bd110273c90835e8f.tar.xz org.eclipse.tcf-cd529d385d79a2ecc6b97a2bd110273c90835e8f.zip |
TCF Tests: improved handling of run control groups.
Diffstat (limited to 'plugins/org.eclipse.tm.tcf.debug')
13 files changed, 409 insertions, 157 deletions
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/ITCFTest.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/ITCFTest.java index a10aecb57..961abadf9 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/ITCFTest.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/ITCFTest.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.tm.internal.tcf.debug.tests; +import org.eclipse.tm.tcf.services.IRunControl; + /** * Each (sub)test in TCF Test Suite should implement this interface. */ @@ -19,4 +21,11 @@ interface ITCFTest { * Start execution of the test. */ void start(); + + /** + * Check if the test don't need the context to stay suspended. + * @param ctx - run control context. + * @return true if it is OK to resume the context. + */ + boolean canResume(IRunControl.RunControlContext ctx); }
\ No newline at end of file diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TCFTestSuite.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TCFTestSuite.java index bdbc981f4..3a55c09b3 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TCFTestSuite.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TCFTestSuite.java @@ -24,6 +24,7 @@ import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IPeer; import org.eclipse.tm.tcf.protocol.Protocol; import org.eclipse.tm.tcf.services.IMemoryMap; +import org.eclipse.tm.tcf.services.IRunControl; import org.eclipse.tm.tcf.services.IPathMap.PathMapRule; /** @@ -264,6 +265,13 @@ public class TCFTestSuite { return active_tests.keySet(); } + boolean canResume(IRunControl.RunControlContext ctx) { + for (ITCFTest t : active_tests.keySet()) { + if (!t.canResume(ctx)) return false; + } + return true; + } + void done(ITCFTest test, Throwable error) { assert active_tests.get(test) != null; if (error != null && !canceled) errors.add(error); diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestAttachTerminate.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestAttachTerminate.java index c7f5b6427..415ddd1b7 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestAttachTerminate.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestAttachTerminate.java @@ -13,6 +13,7 @@ package org.eclipse.tm.internal.tcf.debug.tests; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Random; import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IErrorReport; @@ -27,12 +28,15 @@ class TestAttachTerminate implements ITCFTest, IRunControl.RunControlListener { private final TCFTestSuite test_suite; private final IDiagnostics diag; private final IRunControl rc; + private final Random rnd = new Random(); private int cnt = 0; private final HashMap<String,IRunControl.RunControlContext> ctx_map = new HashMap<String,IRunControl.RunControlContext>(); - private final HashSet<String> process_ids = new HashSet<String>(); + private final HashSet<String> test_ctx_ids = new HashSet<String>(); + private final HashSet<String> suspended_ctx_ids = new HashSet<String>(); + private final HashMap<String,IToken> resume_cmds = new HashMap<String,IToken>(); TestAttachTerminate(TCFTestSuite test_suite, IChannel channel) { this.test_suite = test_suite; @@ -52,32 +56,29 @@ class TestAttachTerminate implements ITCFTest, IRunControl.RunControlListener { if (error != null) { exit(error); } - else { - for (int i = 0; i < list.length; i++) { - if (list[i].equals("RCBP1")) { - startProcess(); - Protocol.invokeLater(1000, new Runnable() { - int cnt = 0; - public void run() { - if (!test_suite.isActive(TestAttachTerminate.this)) return; - cnt++; - if (cnt < 30) { - Protocol.invokeLater(1000, this); - } - else if (test_suite.cancel) { - exit(null); - } - else if (process_ids.isEmpty()) { - exit(new Error("Missing 'contextAdded' event")); - } - else { - exit(new Error("Missing 'contextRemoved' event for " + process_ids)); - } - } - }); - return; + else if (list.length > 0) { + startTestContext(list[rnd.nextInt(list.length)]); + Protocol.invokeLater(100, new Runnable() { + int cnt = 0; + public void run() { + if (!test_suite.isActive(TestAttachTerminate.this)) return; + cnt++; + if (test_suite.cancel) { + exit(null); + } + else if (cnt < 300) { + Protocol.invokeLater(100, this); + for (String id : suspended_ctx_ids) resume(id); + } + else if (test_ctx_ids.isEmpty()) { + exit(new Error("Missing 'contextAdded' event")); + } + else { + exit(new Error("Missing 'contextRemoved' event for " + test_ctx_ids)); + } } - } + }); + return; } exit(null); } @@ -85,9 +86,41 @@ class TestAttachTerminate implements ITCFTest, IRunControl.RunControlListener { } } - private void startProcess() { + public boolean canResume(IRunControl.RunControlContext ctx) { + if (resume_cmds.get(ctx.getID()) != null) return false; + String grp = ctx.getRCGroup(); + if (grp != null) { + for (String id : resume_cmds.keySet()) { + IRunControl.RunControlContext c = ctx_map.get(id); + if (c == null) return false; + if (grp.equals(c.getRCGroup())) return false; + } + } + return true; + } + + private void resume(final String id) { + IRunControl.RunControlContext ctx = ctx_map.get(id); + if (ctx != null && test_suite.canResume(ctx)) { + assert resume_cmds.get(id) == null; + resume_cmds.put(id, ctx.resume(IRunControl.RM_RESUME, 1, new IRunControl.DoneCommand() { + public void doneCommand(IToken token, Exception error) { + assert resume_cmds.get(id) == token; + resume_cmds.remove(id); + if (error instanceof IErrorReport) { + int code = ((IErrorReport)error).getErrorCode(); + if (code == IErrorReport.TCF_ERROR_ALREADY_RUNNING) return; + if (code == IErrorReport.TCF_ERROR_INV_CONTEXT) return; + } + if (error != null) exit(error); + } + })); + } + } + + private void startTestContext(String test_name) { for (int i = 0; i < 4; i++) { - diag.runTest("RCBP1", new IDiagnostics.DoneRunTest() { + diag.runTest(test_name, new IDiagnostics.DoneRunTest() { public void doneRunTest(IToken token, Throwable error, String context_id) { cnt--; if (error != null) { @@ -98,7 +131,7 @@ class TestAttachTerminate implements ITCFTest, IRunControl.RunControlListener { if (ctx_map.get(context_id) == null) { exit(new Error("Missing 'contextAdded' event for context " + context_id)); } - process_ids.add(context_id); + test_ctx_ids.add(context_id); diag.cancelTest(context_id, new IDiagnostics.DoneCancelTest() { public void doneCancelTest(IToken token, Throwable error) { if (error != null) exit(error); @@ -118,6 +151,7 @@ class TestAttachTerminate implements ITCFTest, IRunControl.RunControlListener { } public void containerResumed(String[] context_ids) { + for (String id : context_ids) contextResumed(id); } public void containerSuspended(String main_context, String pc, @@ -149,28 +183,19 @@ class TestAttachTerminate implements ITCFTest, IRunControl.RunControlListener { public void contextRemoved(String[] context_ids) { for (String id : context_ids) { ctx_map.remove(id); - process_ids.remove(id); + test_ctx_ids.remove(id); + suspended_ctx_ids.remove(id); } - if (cnt == 0 && process_ids.isEmpty()) exit(null); + if (cnt == 0 && test_ctx_ids.isEmpty()) exit(null); } public void contextResumed(String context) { + suspended_ctx_ids.remove(context); } public void contextSuspended(String context, String pc, String reason, Map<String,Object> params) { assert context != null; - IRunControl.RunControlContext ctx = ctx_map.get(context); - if (ctx != null && process_ids.contains(ctx.getParentID())) { - ctx.resume(IRunControl.RM_RESUME, 1, new IRunControl.DoneCommand() { - public void doneCommand(IToken token, Exception error) { - if (error instanceof IErrorReport) { - int code = ((IErrorReport)error).getErrorCode(); - if (code == IErrorReport.TCF_ERROR_ALREADY_RUNNING) return; - if (code == IErrorReport.TCF_ERROR_INV_CONTEXT) return; - } - if (error != null) exit(error); - } - }); - } + suspended_ctx_ids.add(context); + resume(context); } }
\ No newline at end of file diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestEcho.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestEcho.java index 9117dce09..b5f33175d 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestEcho.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestEcho.java @@ -16,6 +16,7 @@ import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IErrorReport; import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.services.IDiagnostics; +import org.eclipse.tm.tcf.services.IRunControl; class TestEcho implements ITCFTest, IDiagnostics.DoneEcho { @@ -87,4 +88,8 @@ class TestEcho implements ITCFTest, IDiagnostics.DoneEcho { test_suite.done(this, null); } } + + public boolean canResume(IRunControl.RunControlContext ctx) { + return true; + } }
\ No newline at end of file diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestEchoERR.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestEchoERR.java index bebf589ab..1b49c6c49 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestEchoERR.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestEchoERR.java @@ -22,6 +22,7 @@ import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IErrorReport; import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.services.IDiagnostics; +import org.eclipse.tm.tcf.services.IRunControl; class TestEchoERR implements ITCFTest, IDiagnostics.DoneEchoERR { @@ -110,4 +111,8 @@ class TestEchoERR implements ITCFTest, IDiagnostics.DoneEchoERR { test_suite.done(this, null); } } + + public boolean canResume(IRunControl.RunControlContext ctx) { + return true; + } } diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestEchoFP.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestEchoFP.java index c77f8787f..998defdd2 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestEchoFP.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestEchoFP.java @@ -17,6 +17,7 @@ import java.util.Random; import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.services.IDiagnostics; +import org.eclipse.tm.tcf.services.IRunControl; class TestEchoFP implements ITCFTest, IDiagnostics.DoneEchoFP { @@ -74,4 +75,8 @@ class TestEchoFP implements ITCFTest, IDiagnostics.DoneEchoFP { test_suite.done(this, null); } } + + public boolean canResume(IRunControl.RunControlContext ctx) { + return true; + } } diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestExpressions.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestExpressions.java index a861cb341..a54fd3d4c 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestExpressions.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestExpressions.java @@ -15,10 +15,10 @@ import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Random; import java.util.Set; import org.eclipse.tm.tcf.protocol.IChannel; -import org.eclipse.tm.tcf.protocol.IErrorReport; import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.protocol.Protocol; import org.eclipse.tm.tcf.services.IBreakpoints; @@ -38,13 +38,16 @@ class TestExpressions implements ITCFTest, private final IStackTrace stk; private final IRunControl rc; private final IBreakpoints bp; + private final Random rnd = new Random(); + private String test_id; private String bp_id; private boolean bp_ok; private IDiagnostics.ISymbol sym_func3; private String test_ctx_id; private String process_id; private String thread_id; + private boolean run_to_bp_done; private boolean test_done; private IRunControl.RunControlContext test_ctx; private IRunControl.RunControlContext thread_ctx; @@ -53,6 +56,8 @@ class TestExpressions implements ITCFTest, private String[] stack_trace; private IStackTrace.StackTraceContext[] stack_frames; private String[] local_vars; + private final HashSet<String> suspended_ctx_ids = new HashSet<String>(); + private final HashMap<String,IToken> resume_cmds = new HashMap<String,IToken>(); private final HashMap<String,IRunControl.RunControlContext> ctx_map = new HashMap<String,IRunControl.RunControlContext>(); private final Map<String,IExpressions.Expression> expr_ctx = new HashMap<String,IExpressions.Expression>(); private final Map<String,IExpressions.Value> expr_val = new HashMap<String,IExpressions.Value>(); @@ -129,27 +134,30 @@ class TestExpressions implements ITCFTest, exit(error); } else { - for (int i = 0; i < list.length; i++) { - if (list[i].equals("RCBP1")) { - runTest(); - Protocol.invokeLater(1000, new Runnable() { - int cnt = 0; - public void run() { - if (!test_suite.isActive(TestExpressions.this)) return; - cnt++; - if (cnt < 60) { - Protocol.invokeLater(1000, this); - } - else if (test_suite.cancel) { - exit(null); - } - else { - exit(new Error("Missing 'contextRemoved' event for " + test_ctx_id)); - } + if (list.length > 0) { + test_id = list[rnd.nextInt(list.length)]; + runTest(); + Protocol.invokeLater(100, new Runnable() { + int cnt = 0; + public void run() { + if (!test_suite.isActive(TestExpressions.this)) return; + cnt++; + if (test_suite.cancel) { + exit(null); } - }); - return; - } + else if (cnt < 600) { + Protocol.invokeLater(100, this); + for (String id : suspended_ctx_ids) resume(id); + } + else if (test_ctx_id == null) { + exit(new Error("Timeout waiting for reply of Diagnostics.runTest command")); + } + else { + exit(new Error("Missing 'contextRemoved' event for " + test_ctx_id)); + } + } + }); + return; } exit(null); } @@ -158,6 +166,43 @@ class TestExpressions implements ITCFTest, } } + public boolean canResume(IRunControl.RunControlContext ctx) { + if (test_ctx_id != null && thread_ctx == null) return false; + if (resume_cmds.get(ctx.getID()) != null) return false; + String grp = ctx.getRCGroup(); + if (thread_ctx != null && !test_done) { + if (ctx.getID().equals(thread_id) || grp != null && grp.equals(thread_ctx.getRCGroup())) { + if (sym_func3 == null) return false; + if (suspended_pc == null) return false; + BigInteger pc0 = new BigInteger(sym_func3.getValue().toString()); + BigInteger pc1 = new BigInteger(suspended_pc); + if (pc0.equals(pc1)) return false; + } + } + if (grp != null) { + for (String id : resume_cmds.keySet()) { + IRunControl.RunControlContext c = ctx_map.get(id); + if (c == null) return false; + if (grp.equals(c.getRCGroup())) return false; + } + } + return true; + } + + private void resume(final String id) { + IRunControl.RunControlContext ctx = ctx_map.get(id); + if (ctx != null && test_suite.canResume(ctx)) { + assert resume_cmds.get(id) == null; + resume_cmds.put(id, ctx.resume(IRunControl.RM_RESUME, 1, new IRunControl.DoneCommand() { + public void doneCommand(IToken token, Exception error) { + assert resume_cmds.get(id) == token; + resume_cmds.remove(id); + if (error != null && suspended_ctx_ids.contains(id)) exit(error); + } + })); + } + } + @SuppressWarnings("unchecked") private void runTest() { if (bp_id == null) { @@ -193,7 +238,7 @@ class TestExpressions implements ITCFTest, return; } if (test_ctx_id == null) { - diag.runTest("RCBP1", new IDiagnostics.DoneRunTest() { + diag.runTest(test_id, new IDiagnostics.DoneRunTest() { public void doneRunTest(IToken token, Throwable error, String id) { if (error != null) { exit(error); @@ -201,6 +246,9 @@ class TestExpressions implements ITCFTest, else if (id == null) { exit(new Exception("Test context ID must not be null")); } + else if (ctx_map.get(id) == null) { + exit(new Exception("Missing context added event")); + } else { test_ctx_id = id; runTest(); @@ -221,9 +269,7 @@ class TestExpressions implements ITCFTest, else { test_ctx = ctx; process_id = test_ctx.getProcessID(); - if (!process_id.equals(test_ctx_id)) { - thread_id = test_ctx_id; - } + if (test_ctx.hasState()) thread_id = test_ctx_id; runTest(); } } @@ -303,17 +349,15 @@ class TestExpressions implements ITCFTest, }); return; } - BigInteger pc0 = new BigInteger(sym_func3.getValue().toString()); - BigInteger pc1 = new BigInteger(suspended_pc); - if (!pc0.equals(pc1)) { - suspended_pc = null; - waiting_suspend = true; - thread_ctx.resume(IRunControl.RM_RESUME, 1, new IRunControl.DoneCommand() { - public void doneCommand(IToken token, Exception error) { - if (error != null) exit(error); - } - }); - return; + if (!run_to_bp_done) { + BigInteger pc0 = new BigInteger(sym_func3.getValue().toString()); + BigInteger pc1 = new BigInteger(suspended_pc); + if (!pc0.equals(pc1)) { + waiting_suspend = true; + resume(thread_ctx.getID()); + return; + } + run_to_bp_done = true; } if (stack_trace == null) { stk.getChildren(thread_id, new IStackTrace.DoneGetChildren() { @@ -503,11 +547,24 @@ class TestExpressions implements ITCFTest, return; } test_done = true; - diag.cancelTest(test_ctx_id, new IDiagnostics.DoneCancelTest() { - public void doneCancelTest(IToken token, Throwable error) { - if (error != null) exit(error); - } - }); + if (test_suite.canResume(thread_ctx)) { + final String id = thread_ctx.getID(); + assert resume_cmds.get(id) == null; + resume_cmds.put(id, diag.cancelTest(test_ctx_id, new IDiagnostics.DoneCancelTest() { + public void doneCancelTest(IToken token, Throwable error) { + assert resume_cmds.get(id) == token; + resume_cmds.remove(id); + if (error != null) exit(error); + } + })); + } + else { + Protocol.invokeLater(20, new Runnable() { + public void run() { + runTest(); + } + }); + } } private void exit(Throwable x) { @@ -521,12 +578,12 @@ class TestExpressions implements ITCFTest, //--------------------------- Run Control listener ---------------------------// public void containerResumed(String[] context_ids) { + for (String id : context_ids) contextResumed(id); } public void containerSuspended(String context, String pc, String reason, Map<String,Object> params, String[] suspended_ids) { for (String id : suspended_ids) { - assert id != null; contextSuspended(id, null, null, null); } } @@ -558,6 +615,7 @@ class TestExpressions implements ITCFTest, public void contextRemoved(String[] context_ids) { for (String id : context_ids) { + suspended_ctx_ids.remove(id); ctx_map.remove(id); if (id.equals(test_ctx_id)) { if (test_done) { @@ -576,31 +634,43 @@ class TestExpressions implements ITCFTest, } public void contextResumed(String context) { + suspended_ctx_ids.remove(context); + if (context.equals(thread_id)) { + suspended_pc = null; + } } public void contextSuspended(String context, String pc, String reason, Map<String,Object> params) { + assert context != null; + suspended_ctx_ids.add(context); if (context.equals(thread_id)) { - suspended_pc = pc; - if (waiting_suspend) { - waiting_suspend = false; - runTest(); - } - } - if (test_done) { - IRunControl.RunControlContext ctx = ctx_map.get(context); - if (ctx != null && process_id != null && process_id.equals(ctx.getParentID())) { - ctx.resume(IRunControl.RM_RESUME, 1, new IRunControl.DoneCommand() { - public void doneCommand(IToken token, Exception error) { - if (error instanceof IErrorReport) { - int code = ((IErrorReport)error).getErrorCode(); - if (code == IErrorReport.TCF_ERROR_ALREADY_RUNNING) return; - if (code == IErrorReport.TCF_ERROR_INV_CONTEXT) return; + if (pc == null && thread_ctx != null) { + thread_ctx.getState(new IRunControl.DoneGetState() { + public void doneGetState(IToken token, Exception error, + boolean suspended, String pc, String reason, + Map<String,Object> params) { + if (error != null) { + exit(error); + } + else if (suspended) { + suspended_pc = pc; + if (waiting_suspend) { + waiting_suspend = false; + runTest(); + } } - if (error != null) exit(error); } }); } + else { + suspended_pc = pc; + if (waiting_suspend) { + waiting_suspend = false; + runTest(); + } + } } + resume(context); } //--------------------------- Expressions listener ---------------------------// diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestFileSystem.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestFileSystem.java index 8ebb53a67..5457f5508 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestFileSystem.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestFileSystem.java @@ -19,6 +19,7 @@ import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.protocol.Protocol; import org.eclipse.tm.tcf.services.IFileSystem; +import org.eclipse.tm.tcf.services.IRunControl; import org.eclipse.tm.tcf.services.IFileSystem.DirEntry; import org.eclipse.tm.tcf.services.IFileSystem.FileAttrs; import org.eclipse.tm.tcf.services.IFileSystem.FileSystemException; @@ -424,4 +425,8 @@ class TestFileSystem implements ITCFTest, IFileSystem.DoneStat, if (!test_suite.isActive(this)) return; test_suite.done(this, x); } + + public boolean canResume(IRunControl.RunControlContext ctx) { + return true; + } }
\ No newline at end of file diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestPathMap.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestPathMap.java index b21cc84c7..079a26df3 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestPathMap.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestPathMap.java @@ -18,6 +18,7 @@ import java.util.Random; import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.services.IPathMap; +import org.eclipse.tm.tcf.services.IRunControl; import org.eclipse.tm.tcf.services.IPathMap.PathMapRule; class TestPathMap implements ITCFTest { @@ -175,4 +176,8 @@ class TestPathMap implements ITCFTest { if (!test_suite.isActive(this)) return; test_suite.done(this, x); } + + public boolean canResume(IRunControl.RunControlContext ctx) { + return false; + } } diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestRCBP1.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestRCBP1.java index 32ef648ba..8af7995ea 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestRCBP1.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestRCBP1.java @@ -93,6 +93,8 @@ class TestRCBP1 implements ITCFTest, IRunControl.RunControlListener { private boolean bp_set_done; private boolean bp_change_done; private boolean bp_sync_done; + private boolean data_bp_area_done; + private ILineNumbers.CodeArea data_bp_area; private String data_bp_id; private int data_bp_cnt; private boolean mem_map_test_running; @@ -161,7 +163,19 @@ class TestRCBP1 implements ITCFTest, IRunControl.RunControlListener { @SuppressWarnings("unchecked") public void breakpointStatusChanged(String id, Map<String,Object> status) { - if (bp_list.get(id) != null && test_context != null && bp_cnt < 40 && !mem_map_test_running) { + if (bp_list.get(id) != null && test_context != null && bp_cnt < 40) { + if (test_context != null) { + String prs = test_context.getProcessID(); + if (prs != null) { + for (ITCFTest test : test_suite.getActiveTests()) { + if (test instanceof TestRCBP1) { + TestRCBP1 rcbp = (TestRCBP1)test; + if (!rcbp.mem_map_test_running) continue; + if (prs.equals(rcbp.test_context.getProcessID())) return; + } + } + } + } String s = (String)status.get(IBreakpoints.STATUS_ERROR); if (s != null) exit(new Exception("Invalid BP status: " + s)); Collection<Map<String,Object>> list = (Collection<Map<String,Object>>)status.get(IBreakpoints.STATUS_INSTANCES); @@ -267,6 +281,28 @@ class TestRCBP1 implements ITCFTest, IRunControl.RunControlListener { if (test_id != null) { if (test_ctx_id == null) { startTestContext(); + Protocol.invokeLater(100, new Runnable() { + int cnt = 0; + public void run() { + if (!test_suite.isActive(TestRCBP1.this)) return; + cnt++; + if (test_suite.cancel) { + exit(null); + } + else if (cnt < 600) { + Protocol.invokeLater(100, this); + for (SuspendedContext sc : suspended.values()) { + if (sc.ok_to_resume) resume(sc); + } + } + else if (test_ctx_id == null) { + exit(new Error("Timeout waiting for reply of Diagnostics.runTest command")); + } + else { + exit(new Error("Missing 'contextRemoved' event for " + test_ctx_id)); + } + } + }); return; } if (test_context == null) { @@ -277,6 +313,10 @@ class TestRCBP1 implements ITCFTest, IRunControl.RunControlListener { getSymbols(); return; } + if (!data_bp_area_done) { + getDataBPFile(); + return; + } if (bp_capabilities == null) { getBreakpointCapabilities(); return; @@ -528,6 +568,27 @@ class TestRCBP1 implements ITCFTest, IRunControl.RunControlListener { for (String name : syms) cmds.put(srv_diag.getSymbol(prs, name, done), name); } + private void getDataBPFile() { + ISymbol sym = sym_list.get("tcf_test_func3"); + if (sym == null || srv_line_numbers == null) { + data_bp_area_done = true; + runTest(); + return; + } + srv_line_numbers.mapToSource(test_ctx_id, sym.getValue(), sym.getValue().longValue() + 1, new ILineNumbers.DoneMapToSource() { + public void doneMapToSource(IToken token, Exception error, CodeArea[] areas) { + if (error != null) { + exit(error); + } + else { + if (areas != null && areas.length > 0) data_bp_area = areas[0]; + data_bp_area_done = true; + runTest(); + } + } + }); + } + @SuppressWarnings("unchecked") private void iniBreakpoints() { assert !bp_set_done; @@ -576,7 +637,9 @@ class TestRCBP1 implements ITCFTest, IRunControl.RunControlListener { m[i].put(IBreakpoints.PROP_LOCATION, "&tcf_test_char"); m[i].put(IBreakpoints.PROP_ACCESSMODE, IBreakpoints.ACCESSMODE_WRITE); Number ca = (Number)bp_capabilities.get(IBreakpoints.CAPABILITY_ACCESSMODE); - if (ca != null && (ca.intValue() & IBreakpoints.ACCESSMODE_WRITE) != 0) { + if (data_bp_area != null && ca != null && (ca.intValue() & IBreakpoints.ACCESSMODE_WRITE) != 0) { + m[i].put(IBreakpoints.PROP_FILE, data_bp_area.file); + m[i].put(IBreakpoints.PROP_LINE, data_bp_area.start_line); data_bp_id = (String)m[i].get(IBreakpoints.PROP_ID); } else { @@ -614,16 +677,22 @@ class TestRCBP1 implements ITCFTest, IRunControl.RunControlListener { })); if (id == null) return; get_state_cmds.add(srv_run_ctrl.getContext(id, new IRunControl.DoneGetContext() { - public void doneGetContext(IToken token, Exception error, RunControlContext context) { + public void doneGetContext(IToken token, Exception error, RunControlContext ctx) { get_state_cmds.remove(token); if (test_suite.cancel) return; if (error != null) { exit(error); return; } - if (context.hasState()) { - threads.put(id, context); - get_state_cmds.add(context.getState(new IRunControl.DoneGetState() { + for (ITCFTest t : test_suite.getActiveTests()) { + if (t instanceof TestRCBP1 && ((TestRCBP1)t).threads.get(id) != null) { + exit(new Exception("Invalid or missing 'CreatorID' context attribute.\nContext: " + ctx)); + return; + } + } + if (ctx.hasState()) { + threads.put(id, ctx); + get_state_cmds.add(ctx.getState(new IRunControl.DoneGetState() { public void doneGetState(IToken token, Exception error, boolean susp, String pc, String reason, Map<String, Object> params) { @@ -840,9 +909,13 @@ class TestRCBP1 implements ITCFTest, IRunControl.RunControlListener { exit(new Exception("Invalid contextAdded event:\nContext: " + ctx)); return; } - String p = ctx.getParentID(); - String c = ctx.getCreatorID(); - if (test_ctx_id.equals(c) || test_ctx_id.equals(p)) { + if (isMyContext(ctx)) { + for (ITCFTest t : test_suite.getActiveTests()) { + if (t instanceof TestRCBP1 && ((TestRCBP1)t).threads.get(id) != null) { + exit(new Exception("Invalid or missing 'CreatorID' context attribute.\nContext: " + ctx)); + return; + } + } if (!bp_change_done) { exit(new Exception("Unexpected contextAdded event\nContext: " + ctx)); return; @@ -864,12 +937,19 @@ class TestRCBP1 implements ITCFTest, IRunControl.RunControlListener { for (RunControlContext ctx : contexts) { String id = ctx.getID(); if (id.equals(test_ctx_id)) test_context = ctx; - if (threads.get(id) != null) threads.put(id, ctx); + if (threads.get(id) != null) { + assert isMyContext(ctx); + threads.put(id, ctx); + } } } public void contextException(String id, String msg) { - if (threads.get(id) != null) exit(new Exception("Context exception: " + msg)); + RunControlContext ctx = threads.get(id); + if (ctx != null) { + assert isMyContext(ctx); + exit(new Exception("Context exception: " + msg)); + } } public void contextRemoved(String[] contexts) { @@ -902,6 +982,7 @@ class TestRCBP1 implements ITCFTest, IRunControl.RunControlListener { resume_cmds.remove(id); IRunControl.RunControlContext ctx = threads.get(id); if (ctx == null) return; + assert isMyContext(ctx); if (!ctx.hasState()) { exit(new Exception("Resumed event for context that HasState = false")); return; @@ -941,7 +1022,12 @@ class TestRCBP1 implements ITCFTest, IRunControl.RunControlListener { if (ids != null) { @SuppressWarnings("unchecked") Collection<String> c = (Collection<String>)ids; + HashSet<String> set = new HashSet<String>(); for (String id : c) { + if (!set.add(id)) { + exit(new Exception("Invalid value of 'BPs' attribute: duplicate items")); + return; + } if (bp_list.get(id) != null) { bp_id = id; break; @@ -1028,6 +1114,13 @@ class TestRCBP1 implements ITCFTest, IRunControl.RunControlListener { } } + private boolean isMyContext(IRunControl.RunControlContext ctx) { + // Check if the context was created by this test + return test_ctx_id.equals(ctx.getID()) || + test_ctx_id.equals(ctx.getParentID()) || + test_ctx_id.equals(ctx.getCreatorID()); + } + private boolean isMyBreakpoint(SuspendedContext sc) { // Check if the context is suspended by one of our breakpoints if (!"Breakpoint".equals(sc.reason)) return false; @@ -1055,6 +1148,7 @@ class TestRCBP1 implements ITCFTest, IRunControl.RunControlListener { public void contextSuspended(final String id, String pc, String reason, Map<String, Object> params) { IRunControl.RunControlContext ctx = threads.get(id); if (ctx == null) return; + assert isMyContext(ctx); if (!ctx.hasState()) { exit(new Exception("Suspended event for context that HasState = false")); return; @@ -1113,67 +1207,73 @@ class TestRCBP1 implements ITCFTest, IRunControl.RunControlListener { }); } - private boolean canResume(IRunControl.RunControlContext ctx) { + public boolean canResume(IRunControl.RunControlContext ctx) { + if (test_ctx_id != null && !all_setup_done) return false; + if (resume_cmds.get(ctx.getID()) != null) return false; String grp = ctx.getRCGroup(); + for (IRunControl.RunControlContext x : threads.values()) { + if (x.getID().equals(ctx.getID()) || grp != null && grp.equals(x.getRCGroup())) { + SuspendedContext sc = suspended.get(x.getID()); + if (sc == null) return false; + if (!sc.ok_to_resume) return false; + } + } if (grp != null) { - for (ITCFTest test : test_suite.getActiveTests()) { - if (test instanceof TestRCBP1) { - TestRCBP1 rcbp = (TestRCBP1)test; - for (IRunControl.RunControlContext x : rcbp.threads.values()) { - if (!grp.equals(x.getRCGroup())) continue; - SuspendedContext sc = rcbp.suspended.get(x.getID()); - if (sc == null) { - if (rcbp != TestRCBP1.this) return false; - exit(new Exception("Invalid value of run control group ID")); - return false; - } - if (!sc.ok_to_resume) return false; - } - } + for (String id : resume_cmds.keySet()) { + IRunControl.RunControlContext c = threads.get(id); + if (c == null) return false; + if (grp.equals(c.getRCGroup())) return false; } } return true; } - private void resume(final String id) { + private void resume(String id) { assert done_get_state || resume_cnt == 0; assert resume_cmds.get(id) == null; assert bp_sync_done; assert mem_map_test_done; resume_cnt++; - final SuspendedContext sc = suspended.get(id); - final IRunControl.RunControlContext ctx = threads.get(id); + SuspendedContext sc = suspended.get(id); + IRunControl.RunControlContext ctx = threads.get(id); if (ctx != null && sc != null) { assert !sc.get_state_pending; assert !sc.ok_to_resume; sc.ok_to_resume = true; - if (!canResume(ctx)) return; - int rm = IRunControl.RM_RESUME; - if (isMyBreakpoint(sc)) { - rm = rnd.nextInt(6); - if (!ctx.canResume(rm)) rm = IRunControl.RM_RESUME; - } - resume_cmds.put(id, ctx.resume(rm, 1, new HashMap<String,Object>(), new IRunControl.DoneCommand() { - public void doneCommand(IToken token, Exception error) { - if (test_suite.cancel) return; - if (!test_suite.isActive(TestRCBP1.this)) return; - if (threads.get(id) == null) return; - if (error instanceof IErrorReport && - ((IErrorReport)error).getErrorCode() == IErrorReport.TCF_ERROR_ALREADY_RUNNING && - ctx.getRCGroup() != null) { - error = null; - } - if (error != null) { - exit(error); - return; - } - if (suspended.get(id) == sc || resume_cmds.get(id) == token) { - exit(new Exception("Missing contextResumed event after resume command")); - return; - } - } - })); + resume(sc); + } + } + + private void resume(final SuspendedContext sc) { + assert sc.ok_to_resume; + final String id = sc.id; + final IRunControl.RunControlContext ctx = threads.get(id); + if (!test_suite.canResume(ctx)) return; + int rm = IRunControl.RM_RESUME; + if (isMyBreakpoint(sc)) { + rm = rnd.nextInt(6); + if (!ctx.canResume(rm)) rm = IRunControl.RM_RESUME; } + resume_cmds.put(id, ctx.resume(rm, 1, new HashMap<String,Object>(), new IRunControl.DoneCommand() { + public void doneCommand(IToken token, Exception error) { + if (test_suite.cancel) return; + if (!test_suite.isActive(TestRCBP1.this)) return; + if (threads.get(id) == null) return; + if (error instanceof IErrorReport && + ((IErrorReport)error).getErrorCode() == IErrorReport.TCF_ERROR_ALREADY_RUNNING && + ctx.getRCGroup() != null) { + error = null; + } + if (error != null) { + exit(error); + return; + } + if (suspended.get(id) == sc || resume_cmds.get(id) == token) { + exit(new Exception("Missing contextResumed event after resume command")); + return; + } + } + })); } private void runMemoryTest(final SuspendedContext sc, final Runnable done) { diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestStreams.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestStreams.java index 2384e3c88..e818c583d 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestStreams.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestStreams.java @@ -16,6 +16,7 @@ import java.util.Random; import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.services.IDiagnostics; +import org.eclipse.tm.tcf.services.IRunControl; import org.eclipse.tm.tcf.services.IStreams; class TestStreams implements ITCFTest, IStreams.StreamsListener { @@ -298,4 +299,8 @@ class TestStreams implements ITCFTest, IStreams.StreamsListener { if (!IDiagnostics.NAME.equals(stream_type)) exit(new Exception("Invalid stream type in Streams.disposed event")); if (!stream_ids.remove(stream_id)) exit(new Exception("Invalid stream ID in Streams.disposed event")); } + + public boolean canResume(IRunControl.RunControlContext ctx) { + return true; + } } diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestSysMonitor.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestSysMonitor.java index 568e22b35..c15545d5a 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestSysMonitor.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestSysMonitor.java @@ -16,6 +16,7 @@ import java.util.HashSet; import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IErrorReport; import org.eclipse.tm.tcf.protocol.IToken; +import org.eclipse.tm.tcf.services.IRunControl; import org.eclipse.tm.tcf.services.ISysMonitor; import org.eclipse.tm.tcf.services.ISysMonitor.SysMonitorContext; @@ -112,4 +113,8 @@ class TestSysMonitor implements ITCFTest { if (!test_suite.isActive(this)) return; test_suite.done(this, x); } + + public boolean canResume(IRunControl.RunControlContext ctx) { + return true; + } } diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestTerminals.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestTerminals.java index df6c4edd9..055990468 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestTerminals.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestTerminals.java @@ -7,6 +7,7 @@ import java.util.Random; import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.services.IProcesses; +import org.eclipse.tm.tcf.services.IRunControl; import org.eclipse.tm.tcf.services.ITerminals; import org.eclipse.tm.tcf.services.ITerminals.TerminalContext; @@ -184,4 +185,8 @@ class TestTerminals implements ITCFTest { if (terminals != null) terminals.removeListener(listener); test_suite.done(this, x); } + + public boolean canResume(IRunControl.RunControlContext ctx) { + return true; + } } |