예제 #1
0
        /// <summary>
        /// Publishes all system debug output to all DebugOutput handlers.
        /// </summary>
        private static void ListenThreadProc()
        {
            EventWaitHandle dataAcknowledged  = null;
            EventWaitHandle dataReady         = null;
            IntPtr          debugOutputPages  = IntPtr.Zero;
            IntPtr          mappedDebugOutput = IntPtr.Zero;

            try
            {
                // Create event handles for the two named system events
                dataAcknowledged = CreateEventWaitHandle("DBWIN_BUFFER_READY");

                if (dataAcknowledged == null)
                {
                    TestServices.Trace(
                        "Could not listen for debug output. Check if another application is already listening.");
                    return;
                }

                dataReady = CreateEventWaitHandle("DBWIN_DATA_READY");

                if (dataReady == null)
                {
                    TestServices.Trace(
                        "Could not listen for debug output. Check if another application is already listening.");
                    return;
                }

                // Open the file mapping for the buffer
                debugOutputPages = CreateFileMapping("DBWIN_BUFFER");

                // Map the shared file to memory
                mappedDebugOutput = CreateMemoryMapping(debugOutputPages);

                // Set the events to indicate that we are listening
                _started.Set();
                dataAcknowledged.Set();

                // Create the set of events that we will break on:
                //   - when the buffer is ready
                //   - when the thread has been told to stop listening
                WaitHandle[] waitEvents = new WaitHandle[] {
                    dataReady,
                    _stop
                };

                // WaitAny returns the array index of the event that triggered
                // the wait to return. We will loop until the stop listening
                // event is signaled.
                while (WaitHandle.WaitAny(waitEvents) == 0)
                {
                    // Read the output and send it to the DebugOutput event
                    // handlers
                    int    pid;
                    string output;

                    ReadNextOutput(mappedDebugOutput, out pid, out output);
                    WriteOutput(pid, output);

                    // Acknowledge that the data has been read out of the buffer
                    dataAcknowledged.Set();
                }
            }
            finally
            {
                // Reset the started event to indicate we have stopped listening
                if (_started != null)
                {
                    _started.Reset();
                }

                if (dataAcknowledged != null)
                {
                    dataAcknowledged.Close();
                    dataAcknowledged = null;
                }

                if (dataReady != null)
                {
                    dataReady.Close();
                    dataReady = null;
                }

                if (mappedDebugOutput != IntPtr.Zero)
                {
                    NativeMethods.UnmapViewOfFile(mappedDebugOutput);
                    mappedDebugOutput = IntPtr.Zero;
                }

                if (debugOutputPages != IntPtr.Zero)
                {
                    NativeMethods.CloseHandle(debugOutputPages);
                    debugOutputPages = IntPtr.Zero;
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Will construct the default execution plan.  The default plan orders
        /// test steps by Order parameter, then by phsyical order in the class.
        /// </summary>
        /// <param name="invoker">The invoker to use in the plan.</param>
        /// <param name="test">The test to generate the plan for.</param>
        /// <returns>An execution plan.</returns>
        private static ExecutionPlan BuildDefaultExecutionPlan(
            MethodInvoker invoker, object test)
        {
            // all methods in the test
            MethodInfo[] methods = test.GetType().GetMethods();
            int count = methods.Length;

            // use to store all the calls in the execution plan
            // default plan will only execute a test step method once so the
            // number of calls <= the count of methods
            Dictionary<string, Call> calls =
                new Dictionary<string, Call>(count);

            // use to get the TestStep attribute for the call
            // testSteps are attributes on methods thus they are <= the count
            // of methods.
            Dictionary<Call, TestStepAttribute> testSteps =
                new Dictionary<Call, TestStepAttribute>(count);

            // use to get the orginal physical order of the call
            // default plan will only execute a test step method once so the
            // number of calls <= the count of methods
            Dictionary<Call, int> physicalOrder =
                new Dictionary<Call, int>(count);

            // for every method in the test object
            for (int i = 0; i < count; i++)
            {
                MethodInfo method = methods[i];

                TestStepAttribute attrib =
                    TestServices.GetFirstAttribute(typeof(TestStepAttribute), method)
                    as TestStepAttribute;

                // if an attribute was found, it is a TestStep
                if (attrib != null)
                {
                    // again in the default plan calls map 1:1 to methods that
                    // are test steps, so create a call for the method
                    Call call = new Call(
                        invoker,
                        method,
                        test,
                        new object[method.GetParameters().Length],
                        GetDependencies(attrib, calls));

                    if (!calls.ContainsKey(method.Name))
                    {
                        calls.Add(method.Name, call);
                        physicalOrder.Add(call, i);
                        testSteps.Add(call, attrib);
                    }
                    else
                    {
                        TestServices.Warning(
                            "Skipping TestStep \"{0}\".\n" +
                            "Overloads are not allowed for methods marked with TestStep attribute.",
                            method.Name);
                    }
                }
            }

            // goal: order calls by oder parameter, then by position
            List<Call> sorted = new List<Call>(calls.Values);
            sorted.Sort(delegate(Call left, Call right) 
                {
                    int result = left.Order.CompareTo(right.Order);
                    // if the order is the same sub sort by physical order
                    if (result == 0)
                    {
                        result = physicalOrder[left]
                            .CompareTo(physicalOrder[right]);
                    }
                    return result; 
                });

            // build the execution plan
            ExecutionPlan plan;
            plan.TestSteps = testSteps;
            plan.Calls = sorted;
            return plan;
        }
예제 #3
0
 /// <summary>
 /// Write a message to our trace handler.
 /// </summary>
 private static void TraceMessage(Guid requestId, string format, params object[] args)
 {
     TestServices.Trace("WebServer: {0}: {1}", requestId, string.Format(format, args));
 }