diff --git a/docker-compose.dcproj b/docker-compose.dcproj index 0f0a203ed..45573fce1 100644 --- a/docker-compose.dcproj +++ b/docker-compose.dcproj @@ -10,6 +10,7 @@ + docker-compose.yml diff --git a/docker-compose.migrations.tests.yml b/docker-compose.migrations.tests.yml new file mode 100644 index 000000000..108ba7351 --- /dev/null +++ b/docker-compose.migrations.tests.yml @@ -0,0 +1,30 @@ +version: "3.8" + +services: + directory.infrastructure.migrations.tests: + build: + context: . + dockerfile: src/FilterLists.Directory.Api/Dockerfile + target: test-migrations + networks: + - test-migrations + volumes: + - test-migrations-results:/app/tests/FilterLists.infrastructure.Migrations.Tests/TestResults + depends_on: + - directory.db + + directory.db: + image: postgres:alpine + networks: + - test-migrations + environment: + POSTGRES_USER: ${DIRECTORY_DB_USER} + POSTGRES_PASSWORD: ${DIRECTORY_DB_PASSWORD} + POSTGRES_DB: ${DIRECTORY_DB_DATABASE} + +networks: + test-migrations: + +volumes: + test-migrations-results: + external: true diff --git a/services/FilterLists.sln b/services/FilterLists.sln index 147c8f305..e7ec189fe 100644 --- a/services/FilterLists.sln +++ b/services/FilterLists.sln @@ -43,6 +43,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Data", "Data", "{8F419098-3 directory\data\Tag.json = directory\data\Tag.json EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FilterLists.Directory.Infrastructure.Migrations.Tests", "directory\tests\FilterLists.Directory.Infrastructure.Migrations.Tests\FilterLists.Directory.Infrastructure.Migrations.Tests.csproj", "{8B07EF04-5516-40BB-B21B-CEC6F90EC631}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -73,6 +75,10 @@ Global {8F04C802-830B-4B6D-8D53-5D2A87B4223D}.Debug|Any CPU.Build.0 = Debug|Any CPU {8F04C802-830B-4B6D-8D53-5D2A87B4223D}.Release|Any CPU.ActiveCfg = Release|Any CPU {8F04C802-830B-4B6D-8D53-5D2A87B4223D}.Release|Any CPU.Build.0 = Release|Any CPU + {8B07EF04-5516-40BB-B21B-CEC6F90EC631}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8B07EF04-5516-40BB-B21B-CEC6F90EC631}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8B07EF04-5516-40BB-B21B-CEC6F90EC631}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8B07EF04-5516-40BB-B21B-CEC6F90EC631}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -84,6 +90,7 @@ Global {74C798F8-892A-40F2-8D2E-395E83853771} = {AE5D6471-1B6E-4B06-A313-34EF81F35342} {4F7D51FE-A1F3-4473-A8C3-D57EBDD8E60E} = {AE5D6471-1B6E-4B06-A313-34EF81F35342} {8F419098-3EEB-4B4B-99A8-70555FA93DAF} = {AE5D6471-1B6E-4B06-A313-34EF81F35342} + {8B07EF04-5516-40BB-B21B-CEC6F90EC631} = {AE5D6471-1B6E-4B06-A313-34EF81F35342} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {758B57EF-7505-4BE2-90A2-E2DE2EC32909} diff --git a/services/directory/azure-pipelines.migrate.yaml b/services/directory/azure-pipelines.migrate.yaml index 5766e05e1..fb7b5eaf3 100644 --- a/services/directory/azure-pipelines.migrate.yaml +++ b/services/directory/azure-pipelines.migrate.yaml @@ -145,54 +145,54 @@ steps: echo "##vso[task.setvariable variable=committed;isOutput=true]true" fi - # - task: DockerCompose@0 - # displayName: build test-data - # condition: and(eq(variables['abortJustMigrated.aborted'], 'false'), eq(variables['commitOrAbandon.committed'], 'true'), succeeded()) - # inputs: - # dockerComposeFile: docker-compose.data.tests.yml - # dockerComposeCommand: build api + - task: DockerCompose@0 + displayName: build test-migrations + condition: and(eq(variables['abortJustMigrated.aborted'], 'false'), eq(variables['commitOrAbandon.committed'], 'true'), succeeded()) + inputs: + dockerComposeFile: docker-compose.migrations.tests.yml + dockerComposeCommand: build directory.infrastructure.migrations.tests - # - task: Docker@2 - # displayName: create volume test-data-results - # condition: and(eq(variables['abortJustMigrated.aborted'], 'false'), eq(variables['commitOrAbandon.committed'], 'true'), succeeded()) - # inputs: - # command: volume - # arguments: create test-data-results + - task: Docker@2 + displayName: create volume test-migrations-results + condition: and(eq(variables['abortJustMigrated.aborted'], 'false'), eq(variables['commitOrAbandon.committed'], 'true'), succeeded()) + inputs: + command: volume + arguments: create test-migrations-results - # - task: DockerCompose@0 - # displayName: up test-data db - # condition: and(eq(variables['abortJustMigrated.aborted'], 'false'), eq(variables['commitOrAbandon.committed'], 'true'), succeeded()) - # inputs: - # dockerComposeFile: docker-compose.data.tests.yml - # dockerComposeCommand: up -d mariadb + - task: DockerCompose@0 + displayName: up test-migrations db + condition: and(eq(variables['abortJustMigrated.aborted'], 'false'), eq(variables['commitOrAbandon.committed'], 'true'), succeeded()) + inputs: + dockerComposeFile: docker-compose.migrations.tests.yml + dockerComposeCommand: up -d directory.db - # - task: DockerCompose@0 - # displayName: run test-data - # condition: and(eq(variables['abortJustMigrated.aborted'], 'false'), eq(variables['commitOrAbandon.committed'], 'true'), succeeded()) - # inputs: - # dockerComposeFile: docker-compose.data.tests.yml - # dockerComposeCommand: run api + - task: DockerCompose@0 + displayName: run test-migrations + condition: and(eq(variables['abortJustMigrated.aborted'], 'false'), eq(variables['commitOrAbandon.committed'], 'true'), succeeded()) + inputs: + dockerComposeFile: docker-compose.migrations.tests.yml + dockerComposeCommand: run directory.infrastructure.migrations.tests - # - task: Docker@2 - # displayName: create container test-data-results - # condition: and(eq(variables['abortJustMigrated.aborted'], 'false'), eq(variables['commitOrAbandon.committed'], 'true'), succeededOrFailed()) - # inputs: - # command: container - # arguments: create --name test-data-results -v test-data-results:/results hello-world + - task: Docker@2 + displayName: create container test-migrations-results + condition: and(eq(variables['abortJustMigrated.aborted'], 'false'), eq(variables['commitOrAbandon.committed'], 'true'), succeededOrFailed()) + inputs: + command: container + arguments: create --name test-migrations-results -v test-migrations-results:/results hello-world - # - task: Docker@2 - # displayName: copy out test-data results - # condition: and(eq(variables['abortJustMigrated.aborted'], 'false'), eq(variables['commitOrAbandon.committed'], 'true'), succeededOrFailed()) - # inputs: - # command: cp - # arguments: test-data-results:/results $(System.DefaultWorkingDirectory) + - task: Docker@2 + displayName: copy out test-migrations results + condition: and(eq(variables['abortJustMigrated.aborted'], 'false'), eq(variables['commitOrAbandon.committed'], 'true'), succeededOrFailed()) + inputs: + command: cp + arguments: test-migrations-results:/results $(System.DefaultWorkingDirectory) - # - task: PublishTestResults@2 - # displayName: publish test results - # condition: and(eq(variables['abortJustMigrated.aborted'], 'false'), eq(variables['commitOrAbandon.committed'], 'true'), succeededOrFailed()) - # inputs: - # testResultsFormat: VSTest - # testResultsFiles: "**/*.trx" + - task: PublishTestResults@2 + displayName: publish test results + condition: and(eq(variables['abortJustMigrated.aborted'], 'false'), eq(variables['commitOrAbandon.committed'], 'true'), succeededOrFailed()) + inputs: + testResultsFormat: VSTest + testResultsFiles: "**/*.trx" - task: Bash@3 displayName: push diff --git a/services/directory/docker-compose.migrations.tests.yml b/services/directory/docker-compose.migrations.tests.yml new file mode 100644 index 000000000..445f54309 --- /dev/null +++ b/services/directory/docker-compose.migrations.tests.yml @@ -0,0 +1,30 @@ +version: "3.8" + +services: + directory.infrastructure.migrations.tests: + build: + context: . + dockerfile: src/FilterLists.Directory.Api/Dockerfile + target: test-migrations + networks: + - test-migrations + volumes: + - test-migrations-results:/app/tests/FilterLists.Infrastructure.Migrations.Tests/TestResults + depends_on: + - directory.db + + directory.db: + image: postgres:alpine + networks: + - test-migrations + environment: + POSTGRES_USER: ${DIRECTORY_DB_USER} + POSTGRES_PASSWORD: ${DIRECTORY_DB_PASSWORD} + POSTGRES_DB: ${DIRECTORY_DB_DATABASE} + +networks: + test-migrations: + +volumes: + test-migrations-results: + external: true diff --git a/services/directory/src/FilterLists.Directory.Api/Dockerfile b/services/directory/src/FilterLists.Directory.Api/Dockerfile index b1fc9ff7e..ab59aff0e 100644 --- a/services/directory/src/FilterLists.Directory.Api/Dockerfile +++ b/services/directory/src/FilterLists.Directory.Api/Dockerfile @@ -6,7 +6,7 @@ EXPOSE 80 # init build FROM mcr.microsoft.com/dotnet/core/sdk:3.1-alpine AS build -# restore +# restore API WORKDIR /src COPY directory/src/FilterLists.Directory.Domain/FilterLists.Directory.Domain.csproj FilterLists.Directory.Domain/ COPY directory/src/FilterLists.Directory.Infrastructure/FilterLists.Directory.Infrastructure.csproj FilterLists.Directory.Infrastructure/ @@ -16,7 +16,7 @@ WORKDIR /src/FilterLists.Directory.Api COPY directory/src/FilterLists.Directory.Api/FilterLists.Directory.Api.csproj . RUN dotnet restore -# build +# build API WORKDIR /src COPY directory/src/FilterLists.Directory.Domain/. FilterLists.Directory.Domain/ COPY directory/src/FilterLists.Directory.Infrastructure/. FilterLists.Directory.Infrastructure/ @@ -26,6 +26,19 @@ WORKDIR /src/FilterLists.Directory.Api COPY directory/src/FilterLists.Directory.Api/. . RUN dotnet publish -c Release --no-restore -o /app/publish -p:PublishReadyToRun=true -p:PublishSingleFile=true -p:PublishTrimmed=true -r linux-musl-x64 +# init Infrastructure.Migrations.Tests +FROM build AS test-migrations +ENTRYPOINT ["dotnet", "test", "--logger:trx"] + +# restore Infrastructure.Migrations.Tests +WORKDIR /src/FilterLists.Directory.Infrastructure.Migrations.Tests +COPY directory/tests/FilterLists.Directory.Infrastructure.Migrations.Tests/FilterLists.Directory.Infrastructure.Migrations.Tests.csproj . +RUN dotnet restore + +# build Infrastructure.Migrations.Tests +COPY directory/tests/FilterLists.Directory.Infrastructure.Migrations.Tests/. . +RUN dotnet build -c Release --no-restore -r linux-musl-x64 + # package final FROM base AS final COPY --from=build /app/publish . diff --git a/services/directory/src/FilterLists.Directory.Api/Dockerfile.dev b/services/directory/src/FilterLists.Directory.Api/Dockerfile.dev index f91d1a09b..199b24805 100644 --- a/services/directory/src/FilterLists.Directory.Api/Dockerfile.dev +++ b/services/directory/src/FilterLists.Directory.Api/Dockerfile.dev @@ -6,7 +6,7 @@ EXPOSE 80 # init build FROM mcr.microsoft.com/dotnet/core/sdk:3.1-alpine AS build -# restore +# restore API WORKDIR /src COPY directory/src/FilterLists.Directory.Domain/FilterLists.Directory.Domain.csproj FilterLists.Directory.Domain/ COPY directory/src/FilterLists.Directory.Infrastructure/FilterLists.Directory.Infrastructure.csproj FilterLists.Directory.Infrastructure/ @@ -16,7 +16,7 @@ WORKDIR /src/FilterLists.Directory.Api COPY directory/src/FilterLists.Directory.Api/FilterLists.Directory.Api.csproj . RUN dotnet restore -# build +# build API WORKDIR /src COPY directory/src/FilterLists.Directory.Domain/. FilterLists.Directory.Domain/ COPY directory/src/FilterLists.Directory.Infrastructure/. FilterLists.Directory.Infrastructure/ @@ -26,6 +26,19 @@ WORKDIR /src/FilterLists.Directory.Api COPY directory/src/FilterLists.Directory.Api/. . RUN dotnet publish --no-restore -o /app/publish -r linux-musl-x64 +# init Infrastructure.Migrations.Tests +FROM build AS test-migrations +ENTRYPOINT ["dotnet", "test", "--logger:trx"] + +# restore Infrastructure.Migrations.Tests +WORKDIR /src/FilterLists.Directory.Infrastructure.Migrations.Tests +COPY directory/tests/FilterLists.Directory.Infrastructure.Migrations.Tests/FilterLists.Directory.Infrastructure.Migrations.Tests.csproj . +RUN dotnet restore + +# build Infrastructure.Migrations.Tests +COPY directory/tests/FilterLists.Directory.Infrastructure.Migrations.Tests/. . +RUN dotnet build --no-restore -r linux-musl-x64 + # package final FROM base AS final COPY --from=build /app/publish . diff --git a/services/directory/tests/FilterLists.Directory.Infrastructure.Migrations.Tests/FilterLists.Directory.Infrastructure.Migrations.Tests.csproj b/services/directory/tests/FilterLists.Directory.Infrastructure.Migrations.Tests/FilterLists.Directory.Infrastructure.Migrations.Tests.csproj new file mode 100644 index 000000000..e6f322e47 --- /dev/null +++ b/services/directory/tests/FilterLists.Directory.Infrastructure.Migrations.Tests/FilterLists.Directory.Infrastructure.Migrations.Tests.csproj @@ -0,0 +1,41 @@ + + + + netcoreapp3.1 + latest + enable + false + linux-musl-x64;win10-x64 + + + + Collin M. Barrett + FilterLists + FilterLists Directory + The independent, comprehensive directory of filter and host lists for advertisements, trackers, malware, and annoyances. + Copyright (c) 2020 Collin M. Barrett + https://github.com/collinbarrett/FilterLists + https://filterlists.com + + + + CA1707;CA2007 + + + + CA1707;CA2007 + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/services/directory/tests/FilterLists.Directory.Infrastructure.Migrations.Tests/SeedQueryDbContextTest.cs b/services/directory/tests/FilterLists.Directory.Infrastructure.Migrations.Tests/SeedQueryDbContextTest.cs new file mode 100644 index 000000000..d59b5d3d4 --- /dev/null +++ b/services/directory/tests/FilterLists.Directory.Infrastructure.Migrations.Tests/SeedQueryDbContextTest.cs @@ -0,0 +1,31 @@ +using System.Threading; +using System.Threading.Tasks; +using FilterLists.Directory.Infrastructure.Persistence.Queries.Context; +using Microsoft.EntityFrameworkCore; +using Xunit; + +namespace FilterLists.Directory.Infrastructure.Migrations.Tests +{ + public class SeedQueryDbContextTest + { + [Fact] + public async Task Migrate_DoesNotThrowException() + { + var exception = await Record.ExceptionAsync(async () => + { + // allow time for db to init + Thread.Sleep(20000); + + const string connString = "Server=directory.db;Database=filterlists;Uid=filterlists;Pwd=filterlists;"; + var options = new DbContextOptionsBuilder() + .UseNpgsql(connString, m => m.MigrationsAssembly("FilterLists.Directory.Infrastructure.Migrations")) + .EnableSensitiveDataLogging() + .Options; + + await using var context = new QueryDbContext(options); + await context.Database.MigrateAsync(); + }); + Assert.Null(exception); + } + } +} \ No newline at end of file