Exemple #1
0
            public async Task RunAsync()
            {
                PythonThread thread = await _tests.RunAndBreakAsync(FileName, LineNo, breakFilename : BreakFileName, arguments : Arguments, processLoaded : ProcessLoaded, debugOptions : DebugOptions);

                PythonProcess process = thread.Process;

                try
                {
                    var frames             = thread.Frames;
                    var localNamesExpected = Locals.Select(v => v.Expression).ToSet();
                    var paramNamesExpected = Params.Select(v => v.Expression).ToSet();

                    string fileNameExpected;
                    if (BreakFileName == null)
                    {
                        fileNameExpected = Path.GetFullPath(_tests.DebuggerTestPath + FileName);
                    }
                    else if (Path.IsPathRooted(BreakFileName))
                    {
                        fileNameExpected = BreakFileName;
                    }
                    else
                    {
                        fileNameExpected = Path.GetFullPath(_tests.DebuggerTestPath + BreakFileName);
                    }

                    Assert.AreEqual(frames[0].FileName, fileNameExpected, true);

                    if (!IgnoreExtra)
                    {
                        AssertUtil.ContainsExactly(frames[0].Locals.Select(x => x.Expression), localNamesExpected);
                        AssertUtil.ContainsExactly(frames[0].Parameters.Select(x => x.Expression), paramNamesExpected);
                    }

                    foreach (var expectedLocal in Locals)
                    {
                        var actualLocal = frames[0].Locals.First(v => v.Expression == expectedLocal.Expression);
                        expectedLocal.Validate(actualLocal);
                    }

                    foreach (var expectedParam in Params)
                    {
                        var actualParam = frames[0].Parameters.First(v => v.Expression == expectedParam.Expression);
                        expectedParam.Validate(actualParam);
                    }

                    await process.ResumeAsync(TimeoutToken());

                    if (WaitForExit)
                    {
                        _tests.WaitForExit(process);
                    }
                }
                finally
                {
                    if (!process.HasExited)
                    {
                        process.Terminate();
                    }
                }
            }
Exemple #2
0
            public async Task RunAsync()
            {
                string runFileName = RunFileName;

                if (!Path.IsPathRooted(runFileName))
                {
                    runFileName = _tests.DebuggerTestPath + runFileName;
                }

                string breakFileName = BreakFileName;

                if (breakFileName != null && !Path.IsPathRooted(breakFileName))
                {
                    breakFileName = _tests.DebuggerTestPath + breakFileName;
                }

                foreach (var bp in Breakpoints)
                {
                    var fileName = bp.FileName ?? breakFileName ?? runFileName;
                    if (fileName.EndsWith(".py"))
                    {
                        Assert.IsTrue(bp is Breakpoint);
                    }
                    else
                    {
                        Assert.IsTrue(bp is DjangoBreakpoint);
                    }
                }

                var bps                  = new Dictionary <PythonBreakpoint, BreakpointBase>();
                var unboundBps           = new HashSet <Breakpoint>();
                var breakpointsToBeBound = Breakpoints.Count;

                var          debugger = new PythonDebugger();
                PythonThread thread   = null;

                // Used to signal exceptions from debugger event handlers that run on a background thread.
                var backgroundException = new TaskCompletionSource <bool>();

                var processLoaded = new TaskCompletionSource <bool>();
                var process       = _tests.DebugProcess(
                    debugger,
                    runFileName,
                    cwd: WorkingDirectory,
                    arguments: Arguments,
                    resumeOnProcessLoaded: false,
                    onLoaded: async(newproc, newthread) =>
                {
                    try
                    {
                        foreach (var bp in Breakpoints)
                        {
                            var fileName = bp.FileName ?? breakFileName ?? runFileName;

                            PythonBreakpoint breakpoint;
                            Breakpoint pyBP = bp as Breakpoint;
                            if (pyBP != null)
                            {
                                breakpoint = newproc.AddBreakpoint(fileName, pyBP.LineNumber, pyBP.ConditionKind, pyBP.Condition, pyBP.PassCountKind, pyBP.PassCount);
                                unboundBps.Add(pyBP);
                            }
                            else
                            {
                                DjangoBreakpoint djangoBP = bp as DjangoBreakpoint;
                                if (djangoBP != null)
                                {
                                    breakpoint = newproc.AddDjangoBreakpoint(fileName, djangoBP.LineNumber);
                                    // Django breakpoints are never bound.
                                    --breakpointsToBeBound;
                                }
                                else
                                {
                                    Assert.Fail("Unknown breakpoint type.");
                                    return;
                                }
                            }

                            // Bind failed and succeeded events expect to find the breakpoint
                            // in the dictionary, so update it before sending the add request.
                            bps.Add(breakpoint, bp);
                            await breakpoint.AddAsync(TimeoutToken());
                        }

                        OnProcessLoaded?.Invoke(newproc);

                        thread = newthread;
                        processLoaded.SetResult(true);
                    }
                    catch (Exception ex)
                    {
                        backgroundException.TrySetException(ex);
                    }
                },
                    interpreterOptions: InterpreterOptions
                    );

                int breakpointsBound    = 0;
                int breakpointsNotBound = 0;
                int nextExpectedHit     = 0;

                var allBreakpointsHit        = new TaskCompletionSource <bool>();
                var allBreakpointBindResults = new TaskCompletionSource <bool>();

                if (breakpointsToBeBound == 0)
                {
                    allBreakpointBindResults.SetResult(true);
                }

                try
                {
                    process.BreakpointBindFailed += (sender, args) =>
                    {
                        try
                        {
                            global::DebuggerTests.BaseDebuggerTests.Breakpoint bp = (Breakpoint)bps[args.Breakpoint];
                            if (bp != null && !(bp.IsBindFailureExpected ?? IsBindFailureExpected))
                            {
                                Assert.Fail("Breakpoint at {0}:{1} failed to bind.", bp.FileName ?? breakFileName ?? runFileName, bp.LineNumber);
                            }
                            ++breakpointsNotBound;
                            if (breakpointsBound + breakpointsNotBound == breakpointsToBeBound)
                            {
                                allBreakpointBindResults.SetResult(true);
                            }
                        }
                        catch (Exception ex)
                        {
                            backgroundException.TrySetException(ex);
                        }
                    };

                    process.BreakpointBindSucceeded += (sender, args) =>
                    {
                        try
                        {
                            global::DebuggerTests.BaseDebuggerTests.Breakpoint bp = (Breakpoint)bps[args.Breakpoint];
                            Assert.AreEqual(bp.FileName ?? breakFileName ?? runFileName, args.Breakpoint.Filename);
                            Assert.IsTrue(unboundBps.Remove(bp));
                            ++breakpointsBound;
                            if (breakpointsBound + breakpointsNotBound == breakpointsToBeBound)
                            {
                                allBreakpointBindResults.SetResult(true);
                            }
                        }
                        catch (Exception ex)
                        {
                            backgroundException.TrySetException(ex);
                        }
                    };

                    process.BreakpointHit += async(sender, args) =>
                    {
                        try
                        {
                            if (nextExpectedHit < ExpectedHits.Count)
                            {
                                var bp = Breakpoints[ExpectedHits[nextExpectedHit]];
                                Trace.TraceInformation("Hit {0}:{1}", args.Breakpoint.Filename, args.Breakpoint.LineNo);
                                Assert.AreSame(bp, bps[args.Breakpoint]);

                                if (bp.RemoveWhenHit)
                                {
                                    await args.Breakpoint.RemoveAsync(TimeoutToken());
                                }

                                if (bp.ExpectHitOnMainThread ?? ExpectHitOnMainThread)
                                {
                                    Assert.AreSame(thread, args.Thread);
                                }

                                bp.OnHit?.Invoke(args);

                                if (++nextExpectedHit == ExpectedHits.Count)
                                {
                                    allBreakpointsHit.SetResult(true);
                                }
                            }

                            try
                            {
                                await process.ResumeAsync(TimeoutToken());
                            }
                            catch (TaskCanceledException)
                            {
                                // If we don't wait for exit, the Terminate() call
                                // will cause ResumeAsync to be canceled.
                                if (WaitForExit)
                                {
                                    throw;
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            backgroundException.TrySetException(ex);
                        }
                    };

                    await process.StartAsync();

                    Assert.IsTrue(WaitForAny(10000, processLoaded.Task, backgroundException.Task), "Timed out waiting for process load");

                    await process.AutoResumeThread(thread.Id, TimeoutToken());

                    if (breakpointsToBeBound > 0)
                    {
                        Assert.IsTrue(WaitForAny(10000, allBreakpointBindResults.Task, backgroundException.Task), "Timed out waiting for breakpoints to bind");
                    }
                }
                finally
                {
                    if (WaitForExit)
                    {
                        _tests.WaitForExit(process);
                    }
                    else
                    {
                        Assert.IsTrue(WaitForAny(20000, allBreakpointsHit.Task, backgroundException.Task), "Timed out waiting for breakpoints to hit");
                        process.Terminate();
                    }
                }

                if (backgroundException.Task.IsFaulted)
                {
                    backgroundException.Task.GetAwaiter().GetResult();
                }

                Assert.AreEqual(ExpectedHits.Count, nextExpectedHit);
                Assert.IsTrue(unboundBps.All(bp => bp.IsBindFailureExpected ?? IsBindFailureExpected));
            }