public void Another_monitor_can_safely_attach_and_deattach_to_existsing_session() { using (var testProcess = new TestProcessHandle()) { using (var monitor = GCMonitor.StartForProcess(testProcess.Process.Id)) { var observer = Substitute.For <IObserver <GCInfo> >(); monitor.Subscribe(observer); using (var monitor2 = GCMonitor.StartForProcess(testProcess.Process.Id)) { var observer2 = Substitute.For <IObserver <GCInfo> >(); monitor2.Subscribe(observer2); testProcess.MakeGC(2); TestHelpers.ShouldPassIn(() => { observer.Received(1).OnNext(Arg.Is <GCInfo>(i => IsInducedGc(i, 2))); }, 5.Seconds(), 25.Milliseconds()); } testProcess.MakeGC(2); TestHelpers.ShouldPassIn(() => { // the first monitor should continue to receive GCs observer.Received(2).OnNext(Arg.Is <GCInfo>(i => IsInducedGc(i, 2))); }, 5.Seconds(), 25.Milliseconds()); } } }
public void Catches_gc_events() { using (var testProcess = new TestProcessHandle()) using (var monitor = GCMonitor.StartForProcess(testProcess.Process.Id)) { var observer = Substitute.For <IObserver <GCInfo> >(); observer.When(o => o.OnNext(Arg.Any <GCInfo>())).Do(ci => DumpGCInfo(ci.Arg <GCInfo>())); monitor.Subscribe(observer); var depth = 2; testProcess.MakeGC(depth); TestHelpers.ShouldPassIn(() => { observer .Received(1) .OnNext(Arg.Is <GCInfo>(i => IsInducedGc(i, depth))); }, 3.Seconds(), 25.Milliseconds()); } }
[TestCase(64)] // Max ETW sessions per host //This cases sometimes fail // [TestCase(256)] // [TestCase(512)] public void Can_create_many_gc_monitors(int count) { using (var testProcess = new TestProcessHandle()) { var monitors = new GCMonitor[count]; var observers = new IObserver <GCInfo> [count]; for (var i = 0; i < count; i++) { observers[i] = Substitute.For <IObserver <GCInfo> >(); monitors[i] = GCMonitor.StartForProcess(testProcess.Process.Id); monitors[i].Subscribe(observers[i]); } testProcess.MakeGC(2); var received = new List <int>(); try { TestHelpers.ShouldPassIn(() => { var receivedCount = 0; foreach (var observer in observers) { try { observer.Received(1).OnNext(Arg.Is <GCInfo>(i => IsInducedGc(i, 2))); receivedCount++; } catch { } } received.Add(receivedCount); receivedCount.Should().Be(observers.Length); }, 10.Seconds(), 100.Milliseconds()); } finally { Console.WriteLine($"Called: {received.Count}. Received: {string.Join(",", received)}."); } } }
public void When_monitor_which_created_etw_session_disposes_other_should_continue_to_get_events() { using (var testProcess = new TestProcessHandle()) { using (var firstM = GCMonitor.StartForProcess(testProcess.Process.Id)) { var firstO = Substitute.For <IObserver <GCInfo> >(); firstM.Subscribe(firstO); using (var secondM = GCMonitor.StartForProcess(testProcess.Process.Id)) { var secondO = Substitute.For <IObserver <GCInfo> >(); secondM.Subscribe(secondO); // application which created the first monitor exits Console.WriteLine("Disposing first monitor"); firstM.Dispose(); Console.WriteLine("Disposed first monitor"); // let some time pass... Thread.Sleep(1000); testProcess.MakeGC(2); try { TestHelpers.ShouldPassIn(() => { secondO.Received(1).OnNext(Arg.Is <GCInfo>(i => IsInducedGc(i, 2))); }, 5.Seconds(), 25.Milliseconds()); } catch (Exception) { Console.WriteLine("Waiting on second monitor failed"); throw; } } } } }