public void Setup_Always_DoesNotHaveNonThreadSafeSingletons() { // arrange var container = new Container { Options = { AllowOverridingRegistrations = true } }; ProfilingLibrary.Setup(() => null, container); var assembly = typeof(ProfilingLibrary).Assembly; // act var result = container .GetRegistrationsInfo(x => x.Lifestyle == Lifestyle.Singleton && x.ServiceType.Assembly == assembly) .Where(x => !x.HasSingletonAttribute && x.HasNotThreadSafeMembers && !x.ImplementationType.Name.EndsWith("Configuration")) .Select(x => $"Potential non thread safe singleton {x.ImplementationType}:\n" + $"{string.Join(Environment.NewLine, x.NotThreadSafeMembers)}\n\n") .ToList(); // assert result.Should() .BeEmpty(because: Environment.NewLine + "there are potential non thread safe singleton registrations " + "which are not marked with [Singleton] attribute." + Environment.NewLine + Environment.NewLine + string.Join(Environment.NewLine, result)); }
public async Task Dataflow_CorrectlyRecordsTheSessionAsync() { // arrange var profiler_results_storage = new TestProfilerResultsStorage(); ProfilingLibrary.Setup(() => null); ProfilingLibrary.Container.RegisterSingleton <IProfilerLogger, TestsProfilerLogger>(); ProfilingLibrary.Container.RegisterInstance <IProfilerResultsStorage>(profiler_results_storage); ProfilingLibrary.Container.RegisterSingleton <IProfilerConfiguration, TestProfilerConfiguration>(); var exceptions = new List <Exception>(); var dataflow = DataflowFluent .ReceiveDataOfType <int>() .TransformAsync(async id => { var item = new DataflowItemContext { Id = id, ProfileSession = ProfilingLibrary.StartProfiling() }; using (ProfilingLibrary.Profile(item.ProfileSession, new ProfileOperationSpecification("a"))) { await Task.Delay(50).ConfigureAwait(true); } return(item); }) .ProcessAsync(async item => { using (ProfilingLibrary.Profile(item.ProfileSession, new ProfileOperationSpecification("b"))) { await Task.Delay(50).ConfigureAwait(true); } }) .ActionAsync(item => { ProfilingLibrary.StopProfiling(item.ProfileSession); return(Task.CompletedTask); }) .WithDefaultExceptionLogger((ex, obj) => exceptions.Add(ex)) .CreateDataflow(); // act await dataflow.ProcessAsync(Enumerable.Range(0, 10)).ConfigureAwait(false); // assert exceptions.Should().BeEmpty(); profiler_results_storage.ProfileSessions.ToArray() .SelectMany(x => x.Operations) .Select(x => x.Name) .GroupBy(x => x) .Select(x => new { Name = x.Key, Count = x.Count() }) .Should().BeEquivalentTo(new { Name = "a", Count = 10 }, new { Name = "b", Count = 10 }); }
public void Always_DbConnectionTypeShouldBeEquivalentTo() { // arrange ProfilingLibrary.Setup(() => null); // act var connection = "server=localhost; database=TestDb; Integrated Security=True; Max Pool Size=5".CreateDbConnection(); var connectionType = connection.GetType(); // assert connectionType.Should().Be(typeof(ProfiledDbConnection)); }
public void Setup_Always_DoesNotHaveThreadSafeNonSingletons() { // arrange var container = new Container { Options = { AllowOverridingRegistrations = true } }; ProfilingLibrary.Setup(() => null, container); var assembly = typeof(ProfilingLibrary).Assembly; // act IList <SimpleInjectorRegistrationInfo> registration_infos; List <string> result; using (AsyncScopedLifestyle.BeginScope(container)) { registration_infos = container.GetRegistrationsInfo(x => x.Lifestyle != Lifestyle.Singleton && x.ServiceType.Assembly == assembly, x => x.KnownNotMutableTypes.Add(typeof(Container))); result = registration_infos .Where(x => !x.HasNotThreadSafeMembers && !x.HasNotSingletonAttribute) .Select(x => $"Potential thread safe non singleton: {x.ImplementationType}.") .OrderBy(x => x) .ToList(); } // assert result.Should() .BeEmpty(because: Environment.NewLine + "there are potential thread safe non singleton registrations " + "which are not marked with [NotSingleton] attribute." + Environment.NewLine + Environment.NewLine + string.Join(Environment.NewLine, result) + Environment.NewLine + Environment.NewLine); foreach (var message in registration_infos.Where(x => !x.HasNotSingletonAttribute) .Select(x => $"Not singleton: {x.ImplementationType}") .OrderBy(x => x)) { Console.WriteLine(message); } }
public void Setup_Always_Verifiable_AndContainsNoDiagnosticWarnings() { // arrange var container = new Container { Options = { AllowOverridingRegistrations = true } }; ProfilingLibrary.Setup(() => null, container); // act, assert container.Verify(); var result = Analyzer.Analyze(container); result = result.Where(x => x.DiagnosticType != DiagnosticType.SingleResponsibilityViolation).ToArray(); result.Should().BeEmpty(because: Environment.NewLine + string.Join(Environment.NewLine, result.Select(x => x.Description))); }
public void MultithreadStressTest_DoesNotThrow() { // arrange ProfilingLibrary.Setup(() => null); ProfilingLibrary.Container.RegisterSingleton <IProfilerLogger, TestsProfilerLogger>(); var tasks = Enumerable.Range(0, 10) .Select(x => Task.Run(() => ProfileAsync(x))) .ToArray(); // act var result = Task.WaitAll(tasks, 10000); // assert result.Should().BeTrue(); }
protected void Application_Start() { var config = GlobalConfiguration.Configuration; Container.RegisterWebApiControllers(config); Container.RegisterSingleton <IProfilerResultsStorage, ProfilerJsonResultsStorage>(); // ReSharper disable once ConvertToLocalFunction Func <HttpContextBase> http_context_factory = () => { var result = HttpContextAsyncLocal.Value; if (result == null) { var http_context = HttpContext.Current; if (http_context != null) { result = new HttpContextWrapper(http_context); HttpContextAsyncLocal.Value = result; } } return(result); }; ProfilingLibrary.Setup(http_context_factory, Container); Container.RegisterSingleton <IProfilerResultsStorage, ProfilerJsonResultsStorage>(); config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(Container); config.MapHttpAttributeRoutes(); config.Formatters.Remove(config.Formatters.XmlFormatter); config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new StringEnumConverter()); config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); config.Formatters.JsonFormatter.SerializerSettings.DateFormatHandling = DateFormatHandling.IsoDateFormat; config.EnsureInitialized(); Container.Verify(); }
public static async Task Main() { try { ConfigurationManager.AppSettings["Profiling.Enabled"] = "true"; ConfigurationManager.AppSettings["Profiling.ResultsProcessBatchDelay"] = "00:00:00"; ConfigurationManager.AppSettings["Profiling.ResultsProcessMaxBatchSize"] = "1"; var container = new Container { Options = { AllowOverridingRegistrations = true } }; ProfilingLibrary.Setup(() => null, container); container.RegisterSingleton <IProfilerLogger, ConsoleProfilerLogger>(); container.RegisterSingleton <IProfilerResultsStorage, ConsoleProfileResultsStorage>(); container.Verify(); ProfilingLibrary.StartProfiling(); using (var connection = ConfigurationManager.ConnectionStrings["Test"].CreateDbConnection()) { connection.Execute(@"truncate table TestRocksProfilingTable"); var count = connection.Execute(@"insert TestRocksProfilingTable(Data) values (@data)", new[] { new { data = "123" }, new { data = "456" }, new { data = "789" } } ); Console.WriteLine("Inserted rows: {0}", count); } using (new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { using (var connection = ConfigurationManager.ConnectionStrings["Test"].CreateDbConnection()) { var count = connection.Execute(@"insert TestRocksProfilingTable(Data) values (@data)", new[] { new { data = "2 123" }, new { data = "2 456" }, new { data = "2 789" } } ); Console.WriteLine("Inserted rows: {0}", count); } } using (var connection = ConfigurationManager.ConnectionStrings["Test"] .CreateDbConnection()) { var data = (await connection.QueryAsync <string>("select top 1 Data from TestRocksProfilingTable order by Id;" + "waitfor delay '00:00:01'")).FirstOrDefault(); Console.WriteLine("Selected via ADO: {0}", data); } ProfilingLibrary.StopProfiling(new Dictionary <string, object> { { "name", "test session" } }); Task.Delay(500).Wait(); } catch (Exception ex) { Console.WriteLine("\n\n{0}\n\n", ex); } }
public static void Main() { try { ConfigurationManager.AppSettings["Profiling.Enabled"] = "true"; ConfigurationManager.AppSettings["Profiling.ResultsProcessBatchDelay"] = "00:00:00"; ConfigurationManager.AppSettings["Profiling.ResultsBufferSize"] = "1"; var container = new Container { Options = { AllowOverridingRegistrations = true } }; ProfilingLibrary.Setup(() => null, container); container.RegisterSingleton <IProfilerLogger, ConsoleProfilerLogger>(); container.RegisterSingleton <IProfilerResultsStorage, ConsoleProfileResultsStorage>(); container.RegisterSingleton <IProfilerEventsHandler, ConsoleProfileEventHandlers>(); container.Verify(); ProfilingLibrary.StartProfiling(); using (var connection = ConfigurationManager.ConnectionStrings["Test"].CreateDbConnection()) { var count = connection.Execute(@"insert TestRocksProfilingTable(Data) values (@data)", new[] { new { data = "123" }, new { data = "456" }, new { data = "789" } } ); Console.WriteLine("Inserted rows: {0}", count); } using (new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { using (var connection = ConfigurationManager.ConnectionStrings["Test"].CreateDbConnection()) { var count = connection.Execute(@"insert TestRocksProfilingTable(Data) values (@data)", new[] { new { data = "123" }, new { data = "456" }, new { data = "789" } } ); Console.WriteLine("Inserted rows: {0}", count); } } using (var connection = ConfigurationManager.ConnectionStrings["Test"] .CreateDbConnection()) { var id = connection.Query <int>("select top 1 Id from TestRocksProfilingTable order by Id desc").FirstOrNull(); Console.WriteLine("Selected via ADO: {0}", id); } ProfilingLibrary.StopProfiling(new Dictionary <string, object> { { "name", "test session" } }); Task.Delay(500).Wait(); } // ReSharper disable once CatchAllClause catch (Exception ex) { Console.WriteLine("\n\n{0}\n\n", ex); } }