コード例 #1
0
        private void FireTestFinished(ITestMethodRunnerCallback callback, StreamingTestFileContext testFileContext, JsRunnerOutput jsRunnerOutput, int testIndex)
        {
            var jsTestCase = jsRunnerOutput as JsTestCase;

            jsTestCase.TestCase.InputTestFile = testFileContext.ReferencedFile.Path;
            AddLineNumber(testFileContext.ReferencedFile, testIndex, jsTestCase);
            callback.TestFinished(jsTestCase.TestCase);
            testFileContext.TestFileSummary.AddTestCase(jsTestCase.TestCase);

            ChutzpahTracer.TraceInformation("Test Case Finished:'{0}'", jsTestCase.TestCase.GetDisplayName());
        }
コード例 #2
0
        private void FireLogOutput(ITestMethodRunnerCallback callback, StreamingTestFileContext testFileContext, JsRunnerOutput jsRunnerOutput)
        {
            var log = jsRunnerOutput as JsLog;

            // This is an internal log message
            if (log.Log.Message.StartsWith(internalLogPrefix))
            {
                ChutzpahTracer.TraceInformation("Phantom Log - {0}", log.Log.Message.Substring(internalLogPrefix.Length).Trim());
                return;
            }

            log.Log.InputTestFile = testFileContext.ReferencedFile.Path;
            callback.FileLog(log.Log);
            testFileContext.TestFileSummary.Logs.Add(log.Log);
        }
コード例 #3
0
        private void FireErrorOutput(ITestMethodRunnerCallback callback, StreamingTestFileContext testFileContext, JsRunnerOutput jsRunnerOutput)
        {
            var error = jsRunnerOutput as JsError;

            error.Error.InputTestFile = testFileContext.ReferencedFile.Path;
            callback.FileError(error.Error);
            testFileContext.TestFileSummary.Errors.Add(error.Error);

            if (testFileContext.TestContext.TestFileSettings.CreateFailedTestForFileError.GetValueOrDefault())
            {
                var fileErrorTest = new TestCase();
                fileErrorTest.InputTestFile = testFileContext.ReferencedFile.Path;
                fileErrorTest.TestName      = string.Format("!! File Error #{0} - Error encountered outside of test case execution !!", testFileContext.TestFileSummary.Errors.Count);
                fileErrorTest.TestResults.Add(new TestResult {
                    Passed = false, StackTrace = error.Error.StackAsString ?? error.Error.FormatStackObject(), Message = error.Error.Message
                });
                callback.TestStarted(fileErrorTest);
                callback.TestFinished(fileErrorTest);

                testFileContext.TestFileSummary.AddTestCase(fileErrorTest);
            }

            ChutzpahTracer.TraceError("Eror recieved from Phantom {0}", error.Error.Message);
        }
コード例 #4
0
        private IList <TestFileSummary> ReadFromStream(StreamReader stream, TestContext testContext, TestOptions testOptions, IList <StreamingTestFileContext> streamingTestFileContexts, IList <Action <StreamingTestFileContext> > deferredEvents, ITestMethodRunnerCallback callback, bool debugEnabled)
        {
            var testIndex = 0;

            string line;
            StreamingTestFileContext currentTestFileContext = null;

            if (streamingTestFileContexts.Count == 1)
            {
                currentTestFileContext = streamingTestFileContexts.First();
            }


            while ((line = stream.ReadLine()) != null)
            {
                if (debugEnabled)
                {
                    Console.WriteLine(line);
                }

                var match = prefixRegex.Match(line);
                if (!match.Success)
                {
                    continue;
                }
                var type = match.Groups["type"].Value;
                var json = match.Groups["json"].Value;

                // Only update last event timestamp if it is an important event.
                // Log and error could happen even though no test progress is made
                if (!type.Equals("Log") && !type.Equals("Error"))
                {
                    lastTestEvent = DateTime.Now;
                }


                try
                {
                    switch (type)
                    {
                    case "FileStart":

                        FireFileStarted(callback, testContext);

                        break;

                    case "CoverageObject":

                        var jsCov = jsonSerializer.Deserialize <JsCoverage>(json);

                        if (currentTestFileContext == null)
                        {
                            AddDeferredEvent((fileContext) => FireCoverageObject(callback, fileContext, jsCov), deferredEvents);
                        }
                        else
                        {
                            FireCoverageObject(callback, currentTestFileContext, jsCov);
                        }

                        break;

                    case "FileDone":

                        var jsFileDone = jsonSerializer.Deserialize <JsFileDone>(json);
                        FireFileFinished(callback, testContext.InputTestFilesString, streamingTestFileContexts, jsFileDone);

                        break;

                    case "TestStart":
                        var jsTestCaseStart = jsonSerializer.Deserialize <JsTestCase>(json);
                        StreamingTestFileContext newContext = null;
                        var testName   = jsTestCaseStart.TestCase.TestName.Trim();
                        var moduleName = (jsTestCaseStart.TestCase.ModuleName ?? "").Trim();


                        var fileContexts = GetFileMatches(testName, streamingTestFileContexts);
                        if (fileContexts.Count == 0 && currentTestFileContext == null)
                        {
                            // If there are no matches and not file context has been used yet
                            // then just choose the first context
                            newContext = streamingTestFileContexts[0];
                        }
                        else if (fileContexts.Count == 0)
                        {
                            // If there is already a current context and no matches we just keep using that context
                            // unless this test name has been used already in the current context. In that case
                            // move to the next one that hasn't seen this file yet

                            var testAlreadySeenInCurrentContext = currentTestFileContext.HasTestBeenSeen(moduleName, testName);
                            if (testAlreadySeenInCurrentContext)
                            {
                                newContext = streamingTestFileContexts.FirstOrDefault(x => !x.HasTestBeenSeen(moduleName, testName)) ?? currentTestFileContext;
                            }
                        }
                        else if (fileContexts.Count > 1)
                        {
                            // If we found the test has more than one file match
                            // try to choose the best match, otherwise just choose the first one

                            // If we have no file context yet take the first one
                            if (currentTestFileContext == null)
                            {
                                newContext = fileContexts.First();
                            }
                            else
                            {
                                // In this case we have an existing file context so we need to
                                // 1. Check to see if this test has been seen already on that context
                                //    if so we need to try the next file context that matches it
                                // 2. If it is not seen yet in the current context and the current context
                                //    is one of the matches then keep using it

                                var testAlreadySeenInCurrentContext = currentTestFileContext.HasTestBeenSeen(moduleName, testName);
                                var currentContextInFileMatches     = fileContexts.Any(x => x == currentTestFileContext);
                                if (!testAlreadySeenInCurrentContext && currentContextInFileMatches)
                                {
                                    // Keep the current context
                                    newContext = currentTestFileContext;
                                }
                                else
                                {
                                    // Either take first not used context OR the first one
                                    newContext = fileContexts.Where(x => !x.IsUsed).FirstOrDefault() ?? fileContexts.First();
                                }
                            }
                        }
                        else if (fileContexts.Count == 1)
                        {
                            // We found a unique match
                            newContext = fileContexts[0];
                        }


                        if (newContext != null && newContext != currentTestFileContext)
                        {
                            currentTestFileContext = newContext;
                            testIndex = 0;
                        }

                        currentTestFileContext.IsUsed = true;

                        currentTestFileContext.MarkTestSeen(moduleName, testName);

                        PlayDeferredEvents(currentTestFileContext, deferredEvents);

                        jsTestCaseStart.TestCase.InputTestFile = currentTestFileContext.ReferencedFile.Path;
                        callback.TestStarted(jsTestCaseStart.TestCase);

                        break;

                    case "TestDone":
                        var jsTestCaseDone   = jsonSerializer.Deserialize <JsTestCase>(json);
                        var currentTestIndex = testIndex;

                        FireTestFinished(callback, currentTestFileContext, jsTestCaseDone, currentTestIndex);

                        testIndex++;

                        break;

                    case "Log":
                        var log = jsonSerializer.Deserialize <JsLog>(json);

                        if (currentTestFileContext != null)
                        {
                            FireLogOutput(callback, currentTestFileContext, log);
                        }
                        else
                        {
                            AddDeferredEvent((fileContext) => FireLogOutput(callback, fileContext, log), deferredEvents);
                        }
                        break;

                    case "Error":
                        var error = jsonSerializer.Deserialize <JsError>(json);
                        if (currentTestFileContext != null)
                        {
                            FireErrorOutput(callback, currentTestFileContext, error);
                        }
                        else
                        {
                            AddDeferredEvent((fileContext) => FireErrorOutput(callback, fileContext, error), deferredEvents);
                        }

                        break;
                    }
                }
                catch (SerializationException e)
                {
                    // Ignore malformed json and move on
                    ChutzpahTracer.TraceError(e, "Recieved malformed json from Phantom in this line: '{0}'", line);
                }
            }

            return(streamingTestFileContexts.Select(x => x.TestFileSummary).ToList());
        }
コード例 #5
0
        private void FireCoverageObject(ITestMethodRunnerCallback callback, StreamingTestFileContext testFileContext, JsRunnerOutput jsRunnerOutput)
        {
            var jsCov = jsRunnerOutput as JsCoverage;

            testFileContext.TestFileSummary.CoverageObject = coverageEngine.DeserializeCoverageObject(jsCov.Object, testFileContext.TestContext);
        }
コード例 #6
0
        public TestCaseStreamReadResult Read(TestCaseSource <string> testCaseSource, TestOptions testOptions, TestContext testContext, ITestMethodRunnerCallback callback)
        {
            if (testCaseSource == null)
            {
                throw new ArgumentNullException(nameof(testCaseSource));
            }
            if (testOptions == null)
            {
                throw new ArgumentNullException(nameof(testOptions));
            }
            if (testContext == null)
            {
                throw new ArgumentNullException(nameof(testContext));
            }

            var testCaseStreamReadResult = new TestCaseStreamReadResult();


            var codeCoverageEnabled = testOptions.CoverageOptions.ShouldRunCoverage(testContext.TestFileSettings.CodeCoverageExecutionMode);

            var streamingTestFileContexts = testContext.ReferencedFiles
                                            .Where(x => x.IsFileUnderTest)
                                            .Select(x => new StreamingTestFileContext(x, testContext, codeCoverageEnabled))
                                            .ToList();

            var deferredEvents = new List <Action <StreamingTestFileContext> >();


            if (streamingTestFileContexts.Count == 1)
            {
                currentTestFileContext = streamingTestFileContexts.First();
            }

            testCaseSource.Subscribe((line) => ProcessLine(line, testContext, streamingTestFileContexts, deferredEvents, callback, testOptions.DebugEnabled));

            var readerTask = testCaseSource.Open();

            while ((readerTask.Status == TaskStatus.WaitingToRun ||
                    readerTask.Status == TaskStatus.WaitingForActivation ||
                    readerTask.Status == TaskStatus.Running) && testCaseSource.IsAlive)
            {
                Thread.Sleep(100);
            }

            if (readerTask.IsCompleted)
            {
                ChutzpahTracer.TraceInformation("Finished reading stream from test file '{0}'", testContext.FirstInputTestFile);
                testCaseStreamReadResult.TestFileSummaries = streamingTestFileContexts.Select(x => x.TestFileSummary).ToList();
            }
            else
            {
                // Since we timed out make sure we play the deferred events so we do not lose errors
                // We will just attach these events to the first test context at this point since we do
                // not know where they belong
                PlayDeferredEvents(streamingTestFileContexts.FirstOrDefault(), deferredEvents);

                // We timed out so kill the process and return an empty test file summary
                ChutzpahTracer.TraceError("Test file '{0}' timed out after running for {1} milliseconds", testContext.FirstInputTestFile, (DateTime.Now - testCaseSource.LastTestEvent).TotalMilliseconds);


                testCaseSource.Dispose();
                testCaseStreamReadResult.TimedOut          = true;
                testCaseStreamReadResult.TestFileSummaries = testContext.ReferencedFiles.Where(x => x.IsFileUnderTest).Select(file => new TestFileSummary(file.Path)).ToList();
            }

            return(testCaseStreamReadResult);
        }
コード例 #7
0
        private static void PlayDeferredEvents(StreamingTestFileContext currentTestFileContext, IList<Action<StreamingTestFileContext>> deferredEvents)
        {
            try
            {
                if (currentTestFileContext == null)
                {
                    return;
                }

                // Since we found a unique match we need to reply and log the events that came before this 
                // using this file context

                // We lock here since in the event of a timeout this may be run from the timeout handler while the phantom
                // process is still running
                lock (deferredEvents)
                {
                    foreach (var deferredEvent in deferredEvents)
                    {
                        deferredEvent(currentTestFileContext);
                    }

                    deferredEvents.Clear();
                }
            }
            catch (Exception e)
            {
                ChutzpahTracer.TraceError(e, "Unable to play deferred events");
            }
        }
コード例 #8
0
        private void FireErrorOutput(ITestMethodRunnerCallback callback, StreamingTestFileContext testFileContext, JsRunnerOutput jsRunnerOutput)
        {
            var error = jsRunnerOutput as JsError;

            error.Error.InputTestFile = testFileContext.ReferencedFile.Path;
            callback.FileError(error.Error);
            testFileContext.TestFileSummary.Errors.Add(error.Error);

            ChutzpahTracer.TraceError("Eror recieved from Phantom {0}", error.Error.Message);
        }
コード例 #9
0
        private void FireLogOutput(ITestMethodRunnerCallback callback, StreamingTestFileContext testFileContext, JsRunnerOutput jsRunnerOutput)
        {
            var log = jsRunnerOutput as JsLog;

            // This is an internal log message
            if (log.Log.Message.StartsWith(internalLogPrefix))
            {
                ChutzpahTracer.TraceInformation("Phantom Log - {0}", log.Log.Message.Substring(internalLogPrefix.Length).Trim());
                return;
            }

            log.Log.InputTestFile = testFileContext.ReferencedFile.Path;
            callback.FileLog(log.Log);
            testFileContext.TestFileSummary.Logs.Add(log.Log);
        }
コード例 #10
0
 private void FireCoverageObject(ITestMethodRunnerCallback callback, StreamingTestFileContext testFileContext, JsRunnerOutput jsRunnerOutput)
 {
     var jsCov = jsRunnerOutput as JsCoverage;
     testFileContext.TestFileSummary.CoverageObject = testFileContext.TestContext.CoverageEngine.DeserializeCoverageObject(jsCov.Object, testFileContext.TestContext);
 }
コード例 #11
0
        private void FireTestFinished(ITestMethodRunnerCallback callback, StreamingTestFileContext testFileContext, JsRunnerOutput jsRunnerOutput, int testIndex)
        {

            var jsTestCase = jsRunnerOutput as JsTestCase;
            jsTestCase.TestCase.InputTestFile = testFileContext.ReferencedFile.Path;
            AddLineNumber(testFileContext.ReferencedFile, testIndex, jsTestCase);
            callback.TestFinished(jsTestCase.TestCase);
            testFileContext.TestFileSummary.AddTestCase(jsTestCase.TestCase);


            ChutzpahTracer.TraceInformation("Test Case Finished:'{0}'", jsTestCase.TestCase.GetDisplayName());
            
        }
コード例 #12
0
 private void FireTestFinished(ITestMethodRunnerCallback callback, StreamingTestFileContext testFileContext, JsRunnerOutput jsRunnerOutput, int testIndex)
 {
     var jsTestCase = jsRunnerOutput as JsTestCase;
     jsTestCase.TestCase.InputTestFile = testFileContext.ReferencedFile.Path;
     AddLineNumber(testFileContext.ReferencedFile, testIndex, jsTestCase);
     callback.TestFinished(jsTestCase.TestCase);
     testFileContext.TestFileSummary.AddTestCase(jsTestCase.TestCase);
 }