public void Measures_total_CPU_usage()
        {
            using (var testProcess = new TestProcessHandle())
            {
                var meter = new HostCpuUsageMeterFast();
                var cores = ProcessorInfo.LogicalCores;

                var observationsCount = 10;
                var lowValues         = TestHelpers.GetMeterValues(
                    () => meter.GetHostCpuUsage() * cores,
                    TimeSpan.FromMilliseconds(255),
                    observationsCount);

                testProcess.EatCpu(cores - 1);

                var highValues = TestHelpers.GetMeterValues(
                    () => meter.GetHostCpuUsage() * cores,
                    TimeSpan.FromMilliseconds(255),
                    observationsCount);

                Console.WriteLine($"Low values: {string.Join(", ", lowValues)}");
                Console.WriteLine($"High values: {string.Join(", ", highValues)}");

                highValues
                .Count(h => lowValues.Count(l => l < h) > observationsCount * 0.75)
                .Should()
                .BeGreaterOrEqualTo((int)(observationsCount * 0.75));
            }
        }
        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 Process_memory_meter_fails_after_process_exit()
 {
     using (var testProcess = new TestProcessHandle())
         using (var meter = new ProcessMemoryMeter(testProcess.Process.Id))
         {
             testProcess.Dispose();
             new Action(() => meter.GetMemoryInfo()).Should().Throw <InvalidOperationException>();
         }
 }
 public void Does_not_throw()
 {
     using (var testProcess = new TestProcessHandle())
         using (var memMeter = new ProcessMemoryMeter(testProcess.Process.Id))
         {
             var memInfo = memMeter.GetMemoryInfo();
             Console.WriteLine(memInfo);
         }
 }
        private TestProcessHandle ObtainTestProcess()
        {
            if (testProcess != null)
            {
                return(testProcess);
            }
            var p = new TestProcessHandle();

            p.EatMemory(DataSize.FromMegabytes(10).Bytes);
            return(p);
        }
 public void LohSize()
 {
     using (var testProcess = new TestProcessHandle())
         using (var meter = new ManagedMemoryMeter(testProcess.Process.Id))
         {
             var size          = DataSize.FromKilobytes(100);
             var lohSizeBefore = meter.GetManagedMemoryInfo().Heap.LargeObjectHeapSizeBytes;
             testProcess.EatPrivateMemory(size.Bytes);
             testProcess.MakeGC(0);
             var lohSizeAfter = meter.GetManagedMemoryInfo().Heap.LargeObjectHeapSizeBytes;
             (lohSizeAfter - lohSizeBefore).Should().BeGreaterOrEqualTo(size.Bytes);
         }
 }
        public void AllocationRate(int mb, int seconds)
        {
            var size = DataSize.FromMegabytes(mb);
            var rate = (size / seconds).Bytes;

            using (var testProcess = new TestProcessHandle())
                using (var meter = new ManagedMemoryMeter(testProcess.Process.Id))
                {
                    meter.GetManagedMemoryInfo();
                    testProcess.EatPrivateMemory(size.Bytes);
                    Thread.Sleep(seconds.Seconds());
                    testProcess.MakeGC(0);
                    var result = meter.GetManagedMemoryInfo();
                    (result.Heap.AllocatedBytesPerSecond - rate).Should().BeLessThan(rate / 10);
                }
        }
        public void Memory_usage_increases_when_process_eats_memory()
        {
            using (var testProcess = new TestProcessHandle())
                using (var memoryMeter = new HostMemoryMeter())
                {
                    var toEat     = DataSize.FromMegabytes(100).Bytes;
                    var tolerance = DataSize.FromMegabytes(20).Bytes;
                    var beforeEat = memoryMeter.GetHostMemoryInfo().AvailablePhysicalMemoryBytes;
                    testProcess.EatMemory(toEat);
                    Thread.Sleep(100);
                    var afterEat = memoryMeter.GetHostMemoryInfo();

                    Console.WriteLine($"Before: {beforeEat}. After: {afterEat.AvailablePhysicalMemoryBytes}. Diff: {afterEat.AvailablePhysicalMemoryBytes - beforeEat}. Total: {afterEat.TotalPhysicalMemoryBytes}");

                    afterEat.AvailablePhysicalMemoryBytes.Should().BeLessThan(beforeEat - toEat + tolerance);
                }
        }
Exemple #9
0
        public void Measures_threads()
        {
            using (var testProcess = new TestProcessHandle())
                using (var meter = new NativeThreadsMeter(testProcess.Process.Id))
                {
                    var before = meter.GetNativeThreadsCount();
                    Console.WriteLine($"Before: {before}");

                    testProcess.MakeThreads(10);

                    TestHelpers.ShouldPassIn(() =>
                    {
                        var after = meter.GetNativeThreadsCount();
                        Console.WriteLine($"After: {after}");
                        after.Should().BeGreaterOrEqualTo(before + 10);
                    }, 2.Seconds(), 100.Milliseconds());
                }
        }
Exemple #10
0
        public void Measures_CPU_usage_for_process()  //TODO (epeshk): should we set limits or use processor affinity to make this test more stable?
        {
            using (var testProcess = new TestProcessHandle())
                using (var meter = new ProcessCpuUsageMeter(testProcess.Process.Id))
                {
                    var observationsCount = 20;
                    var lowValues         = TestHelpers.GetMeterValues(() => meter.GetCpuUsage(), TimeSpan.FromMilliseconds(100), observationsCount);
                    testProcess.EatCpu(1);
                    var highValues = TestHelpers.GetMeterValues(() => meter.GetCpuUsage(), TimeSpan.FromMilliseconds(100), observationsCount);

                    Console.WriteLine($"Low values: {string.Join(", ", lowValues)}");
                    Console.WriteLine($"High values: {string.Join(", ", highValues)}");

                    highValues
                    .Count(h => lowValues.All(l => l < h))
                    .Should()
                    .BeGreaterOrEqualTo((int)(highValues.Length * 0.75));
                }
        }
        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());
                }
        }
        public void GCMeter_Works()
        {
            using (var testProcess = new TestProcessHandle())
                using (var meter = new ManagedMemoryMeter(testProcess.Process.Id))
                {
                    var before = meter.GetManagedMemoryInfo().GC;
                    Console.WriteLine($"Before: {before}");

                    testProcess.MakeGC(0);
                    testProcess.MakeGC(1);
                    testProcess.MakeGC(2);

                    var after = meter.GetManagedMemoryInfo().GC;
                    Console.WriteLine($"After: {after}");

                    (after.Gen0CollectionsSinceStart - before.Gen0CollectionsSinceStart).Should().BeGreaterOrEqualTo(3);
                    (after.Gen1CollectionsSinceStart - before.Gen1CollectionsSinceStart).Should().BeGreaterOrEqualTo(2);
                    (after.Gen2CollectionsSinceStart - before.Gen2CollectionsSinceStart).Should().BeGreaterOrEqualTo(1);
                }
        }
        public void Process_memory_meter_works_for_private_memory()
        {
            using (var testProcess = new TestProcessHandle())
                using (var meter = new ProcessMemoryMeter(testProcess.Process.Id))
                {
                    var toEat     = DataSize.FromMegabytes(100);
                    var tolerance = DataSize.FromMegabytes(2);

                    var before = meter.GetMemoryInfo();
                    testProcess.EatPrivateMemory(toEat.Bytes);
                    var after = meter.GetMemoryInfo();

                    Console.WriteLine($"Before: ws {before.WorkingSetBytes} pb {before.PrivateBytes}");
                    Console.WriteLine($"After: ws {after.WorkingSetBytes} pb {after.PrivateBytes}");
                    Console.WriteLine($"Diff ws {after.WorkingSetBytes - before.WorkingSetBytes} pb {after.PrivateBytes - before.PrivateBytes}");

                    (after.WorkingSetBytes - before.WorkingSetBytes).Should().BeLessThan(tolerance.Bytes);
                    (after.PrivateBytes - before.PrivateBytes).Should().BeGreaterThan((toEat - tolerance).Bytes);
                }
        }
        [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;
                        }
                    }
                }
            }
        }
 public void GlobalSetup()
 {
     testProcess = ObtainTestProcess();
 }
 public void GlobalCleanup()
 {
     testProcess.Dispose();
     testProcess = null;
 }