public void ThreadSafeStringWriterWritesLinesFromDifferentsTasksSeparately() { // Suppress the flow of parent context here becuase this test method will run in // a task already and we don't want the existing async context to interfere with this. using (ExecutionContext.SuppressFlow()) { // String writer needs to be task aware to write output from different tasks // into different output. The tasks below wait for each other to ensure // we are mixing output from different tasks at the same time. using (var stringWriter = new ThreadSafeStringWriter(CultureInfo.InvariantCulture, "output")) { var task1 = Task.Run(() => { var timeout = Stopwatch.StartNew(); stringWriter.WriteLine("content1"); stringWriter.WriteLine("content1"); stringWriter.WriteLine("content1"); stringWriter.WriteLine("content1"); while (this.task2flag != true && timeout.Elapsed < TimeSpan.FromSeconds(5)) { } stringWriter.WriteLine("content1"); stringWriter.WriteLine("content1"); stringWriter.WriteLine("content1"); stringWriter.WriteLine("content1"); return(stringWriter.ToString()); }); var task2 = Task.Run(() => { stringWriter.WriteLine("content2"); stringWriter.WriteLine("content2"); stringWriter.WriteLine("content2"); stringWriter.WriteLine("content2"); this.task2flag = true; stringWriter.WriteLine("content2"); stringWriter.WriteLine("content2"); stringWriter.WriteLine("content2"); stringWriter.WriteLine("content2"); return(stringWriter.ToString()); }); var task2Output = task2.GetAwaiter().GetResult(); var task1Output = task1.GetAwaiter().GetResult(); // there was no output in the current task, the output should be empty var content = stringWriter.ToString(); content.Should().BeNullOrWhiteSpace(); // task1 and task2 should output into their respective buckets task1Output.Should().NotBeNullOrWhiteSpace(); task2Output.Should().NotBeNullOrWhiteSpace(); task1Output.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Should().OnlyContain(i => i == "content1").And.HaveCount(8); task2Output.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Should().OnlyContain(i => i == "content2").And.HaveCount(8); } } }
/// <summary>Runs executable with the provided arguments</summary> /// <returns>The console output of this program</returns> public ConsoleOutput Run(params string[] arguments) { lock (s_lock) { Console.Write($"{Command} "); Console.WriteLine(string.Join(" ", arguments)); TextWriter consoleOut = Console.Out; ThreadSafeStringWriter stringOut = new ThreadSafeStringWriter(); Console.SetOut(stringOut); try { int exitCode = 0; if (null == VoidMain) { exitCode = Main(arguments); } else { VoidMain(arguments); } ConsoleOutput consoleOutput = new ConsoleOutput() { ExitCode = exitCode, Stdout = stringOut.ToString() }; Console.Write(consoleOutput.Stdout); return(consoleOutput); } finally { Console.SetOut(consoleOut); } } }
public void ThreadSafeStringWriterWriteLineHasContentFromMultipleThreads() { using (var stringWriter = new ThreadSafeStringWriter(CultureInfo.InvariantCulture)) { Action <string> action = (string x) => { for (var i = 0; i < 100000; i++) { // Choose WriteLine since it calls the entire sequence: // Write(string) -> Write(char[]) -> Write(char) stringWriter.WriteLine(x); } }; var task1 = Task.Run(() => action("content1")); var task2 = Task.Run(() => action("content2")); task1.Wait(); task2.Wait(); // Validate that only whole lines are written, not a mix of random chars foreach (var line in stringWriter.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)) { Assert.IsTrue(line.Equals("content1") || line.Equals("content2")); } } }
public void WriteWithMessageShouldWriteToStringWriterForNullCharacters() { var stringWriter = new ThreadSafeStringWriter(null, "test"); this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties); this.testContextImplementation.Write("1 Testing \0 write \0"); StringAssert.Contains(stringWriter.ToString(), "1 Testing \\0 write \\0"); }
public void WriteShouldWriteToStringWriter() { var stringWriter = new ThreadSafeStringWriter(null, "test"); this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties); this.testContextImplementation.Write("{0} Testing write", 1); StringAssert.Contains(stringWriter.ToString(), "1 Testing write"); }
public void WriteWithMessageShouldWriteToStringWriterForReturnCharacters() { var stringWriter = new ThreadSafeStringWriter(null, "test"); this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties); this.testContextImplementation.Write("2 Testing write \n\r"); this.testContextImplementation.Write("3 Testing write\n\r"); StringAssert.Equals(stringWriter.ToString(), "2 Testing write 3 Testing write"); }
public void ClearDiagnosticMessagesShouldClearMessagesFromWriteLine() { var stringWriter = new ThreadSafeStringWriter(null, "test"); this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties); this.testContextImplementation.WriteLine("1 Testing write"); this.testContextImplementation.WriteLine("2 Its a happy day"); this.testContextImplementation.ClearDiagnosticMessages(); Assert.AreEqual(string.Empty, stringWriter.ToString()); }
public void ThreadSafeStringWriterWritesLinesIntoDifferentWritesSeparately() { // Suppress the flow of parent context here becuase this test method will run in // a task already and we don't want the existing async context to interfere with this. using (ExecutionContext.SuppressFlow()) { // The string writer mixes output captured by different instances if they are in the same taks, or under the same task context // and use the same output type. In the any of the "out" writers we should see all the output from the writers marked as "out" // and in any of the debug writers we should see all "debug" output. using (var stringWriter1 = new ThreadSafeStringWriter(CultureInfo.InvariantCulture, "out")) { using (var stringWriter2 = new ThreadSafeStringWriter(CultureInfo.InvariantCulture, "debug")) { using (var stringWriter3 = new ThreadSafeStringWriter(CultureInfo.InvariantCulture, "out")) { using (var stringWriter4 = new ThreadSafeStringWriter(CultureInfo.InvariantCulture, "debug")) { // Writing the data needs to run in a task, because that is how the writer is designed, // because we always run test in a task, so we must not setup the parent context, otherwise // it would capture output of all tests. var result = Task.Run(() => { stringWriter1.WriteLine("out"); stringWriter2.WriteLine("debug"); Task.Run(() => { stringWriter3.WriteLine("out"); stringWriter4.WriteLine("debug"); }).GetAwaiter().GetResult(); return(new { Out = stringWriter1.ToString(), Debug = stringWriter2.ToString() }); }).GetAwaiter().GetResult(); // task1 and task2 should output into their respective buckets result.Out.Should().NotBeNullOrWhiteSpace(); result.Debug.Should().NotBeNullOrWhiteSpace(); var output = result.Out.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); output.Should().OnlyContain(i => i == "out").And.HaveCount(2); var debug = result.Debug.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); debug.Should().OnlyContain(i => i == "debug").And.HaveCount(2); } } } } } }
public void ThreadSafeStringWriterWriteLineHasContentFromMultipleThreads() { using (ExecutionContext.SuppressFlow()) { using (var stringWriter = new ThreadSafeStringWriter(CultureInfo.InvariantCulture, "tst")) { Action <string> action = (string x) => { var count = 10; for (var i = 0; i < count; i++) { // Choose WriteLine since it calls the entire sequence: // Write(string) -> Write(char[]) -> Write(char) stringWriter.WriteLine(x); } }; var task1 = Task.Run(() => { var timeout = Stopwatch.StartNew(); action("content1"); action("content1"); action("content1"); action("content1"); while (this.task2flag != true && timeout.Elapsed < TimeSpan.FromSeconds(5)) { } action("content1"); action("content1"); action("content1"); action("content1"); }); var task2 = Task.Run(() => { action("content2"); action("content2"); action("content2"); action("content2"); this.task2flag = true; action("content2"); action("content2"); action("content2"); action("content2"); }); task2.GetAwaiter().GetResult(); task1.GetAwaiter().GetResult(); var content = stringWriter.ToString(); content.Should().NotBeNullOrWhiteSpace(); // Validate that only whole lines are written, not a mix of random chars var lines = content.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); lines.Should().HaveCountGreaterThan(0); foreach (var line in lines) { Assert.IsTrue(line.Equals("content1") || line.Equals("content2")); } } } }