Base solution for your next web application

Activities of "lojelis"

Hi @ismcagdas,

Here is the specifications of my computer (sorry it's in french but I think you can understand the main parts):

I have used the Stopwatch Class from System.Diagnostics to measure the execution time of the Intialize method from the AbpBootstrapper class, but I haven't been in depth into the Initialize method. How can I measure the execution times of the method calls inside the method Initialize?

Thanks in advance,

Nicolas

Yes I can, here it is:

using System;
using System.IO;
using Abp;
using Abp.AspNetZeroCore;
using Abp.AutoMapper;
using Abp.Configuration.Startup;
using Abp.Dependency;
using Abp.Modules;
using Abp.Net.Mail;
using Abp.TestBase;
using Abp.Zero.Configuration;
using Castle.MicroKernel.Registration;
using Microsoft.Extensions.Configuration;
using Lojelis.COPYlote.Authorization.Users;
using Lojelis.COPYlote.Configuration;
using Lojelis.COPYlote.EntityFrameworkCore;
using Lojelis.COPYlote.MultiTenancy;
using Lojelis.COPYlote.Security.Recaptcha;
using Lojelis.COPYlote.Tests.Configuration;
using Lojelis.COPYlote.Tests.DependencyInjection;
using Lojelis.COPYlote.Tests.UiCustomization;
using Lojelis.COPYlote.Tests.Url;
using Lojelis.COPYlote.Tests.Web;
using Lojelis.COPYlote.UiCustomization;
using Lojelis.COPYlote.Url;
using NSubstitute;
using Lojelis.COPYlote.App;
using Lojelis.COPYlote.Tests.App.UserHelper;

namespace Lojelis.COPYlote.Tests
{
    [DependsOn(
        typeof(COPYloteApplicationModule),
        typeof(COPYloteEntityFrameworkCoreModule),
        typeof(AbpTestBaseModule))]
    public class COPYloteTestModule : AbpModule
    {
        public COPYloteTestModule(COPYloteEntityFrameworkCoreModule abpZeroTemplateEntityFrameworkCoreModule)
        {
            abpZeroTemplateEntityFrameworkCoreModule.SkipDbContextRegistration = true;
        }

        public override void PreInitialize()
        {
            var configuration = GetConfiguration();

            Configuration.UnitOfWork.Timeout = TimeSpan.FromMinutes(30);
            Configuration.UnitOfWork.IsTransactional = false;
            //Configuration.UnitOfWork.OverrideFilter("MayHaveSite",false);

            //Disable static mapper usage since it breaks unit tests (see https://github.com/aspnetboilerplate/aspnetboilerplate/issues/2052)
            Configuration.Modules.AbpAutoMapper().UseStaticMapper = false;

            //Use database for language management
            Configuration.Modules.Zero().LanguageManagement.EnableDbLocalization();

            RegisterFakeService<AbpZeroDbMigrator>();

            IocManager.Register<IAppUrlService, FakeAppUrlService>();
            IocManager.Register<IWebUrlService, FakeWebUrlService>();
            IocManager.Register<IRecaptchaValidator, FakeRecaptchaValidator>();
            IocManager.Register<IUserHelper, FakeUserHelper>();

            Configuration.ReplaceService<IAppConfigurationAccessor, TestAppConfigurationAccessor>();
            Configuration.ReplaceService<IEmailSender, NullEmailSender>(DependencyLifeStyle.Transient);

            Configuration.ReplaceService<IUiThemeCustomizerFactory, NullUiThemeCustomizerFactory>();

            Configuration.Modules.AspNetZero().LicenseCode = configuration["AbpZeroLicenseCode"];

            //Uncomment below line to write change logs for the entities below:
            Configuration.EntityHistory.IsEnabled = true;
            Configuration.EntityHistory.Selectors.Add("COPYloteEntities", typeof(User), typeof(Tenant));
        }

        public override void Initialize()
        {
            ServiceCollectionRegistrar.Register(IocManager);
        }

        private void RegisterFakeService<TService>()
            where TService : class
        {
            IocManager.IocContainer.Register(
                Component.For<TService>()
                    .UsingFactoryMethod(() => Substitute.For<TService>())
                    .LifestyleSingleton()
            );
        }

        private static IConfigurationRoot GetConfiguration()
        {
            return AppConfigurations.Get(Directory.GetCurrentDirectory(), addUserSecrets: true);
        }
    }
}

I can't share the project because I have confidentiality engagements with my client. However I have discovered that some other ABP users had the issue in the past: https://support.aspnetzero.com/QA/Questions/444.

That's exactly my case. I have studied more in details the problem and it comes from the class AbpBootstrapper and its method Initialize.

Did you find a solution in the past?

Best regards, Nicolas

Another relevant piece of code. The following takes 2 minutes to run:

public abstract class AppTestBase : AbpIntegratedTestBase<COPYloteTestModule>
{
     protected AppTestBase() : base(true, null)
     {
     }
 }
 
public class Hello_Test : AppTestBase
{
   [Fact]
    public void Should_Write_Hello_World()
    {
        Console.WriteLine("Hello World");
    }
}

While this takes 182ms:

public abstract class AppTestBase : AbpIntegratedTestBase<COPYloteTestModule>
{
     protected AppTestBase() : base(false, null)
     {
     }
 }
 
public class Hello_Test : AppTestBase
{
   [Fact]
    public void Should_Write_Hello_World()
    {
        Console.WriteLine("Hello World");
    }
}

The only difference is the parameter initializeAbp of the base class AbpIntegratedTestBase which is turned to false.

So what can slow down ABP initialization? Is it the total number of app services in the project? Currently we have 70 services. With :

  • 173 GET methods
  • 158 POST methods
  • 43 PUT methods
  • 26 DELETE methods

Which makes 400 endpoints. Maybe the initialization is slow because of this? Have you ever try to use ABP for a project of this size (or even bigger)?

Best regards, Nicolas

Hi thanks for your reply!

I am requisting the autorisation from my hierachy to share the project with you. While I am waiting for the answer, I can share some small pieces of code to give you some clues.

 public abstract class AppTestBase : AbpIntegratedTestBase<COPYloteTestModule>
 {
    protected AppTestBase() : base(true, null)
    {
        //SeedTestData();
        //LoginAsDefaultTenantAdmin();
    }
 }

I have voluntary commented the two lines to see if the performance issue does not come from here but without success. The test still take 2 minutes to run. Here is the prototype of our test class:

    public class EmployeService_Tests : AppTestBase
    {
        [Fact]
        public async void Should_Get_All_The_Employees()
        {
            var employes = await _employeService.GetAllAsync();
            Assert.Equal(5, employes.Items.Count);
        }
    }

Regards, Nicolas

Hi!

I have troubles using the test project of the ASP.NET Zero template. The tests are working correctly however, they take a lot of time to run. I think that the issue comes from the class AbpIntegratedTestBase. I explain myself with two examples:

  • I have a test class that does not inherit from AbpIntegratedTestBase. The class only reads some to text files, extract data and check if everything is correct. The test takes 33ms to run.
  • I have another test class that makes a call to the application's API. The test class inherits from AbpIntegratedTestBase to scaffold the app before testing. In the test I only make a single call to an endpoint that returns a basic list of items. It tooks 2 minutes to run...

I let you imagine the time it takes to run all the tests suit (more than an hour). It makes the test project totaly worthlessness. I would like to know if you have a solution to solve this issue because the test project is one of the best part of your template. Thanks in advance.

Best regards, Nicolas Prugne

Showing 1 to 6 of 6 entries