Browse Source

Simplify build (#952)

* Simplify build.

* Simplification.
pull/954/head
Sebastian Stehle 4 years ago
committed by GitHub
parent
commit
379b14d457
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 119
      .github/workflows/dev.yml
  2. 155
      .github/workflows/release.yml
  3. 29
      backend/src/Squidex.Domain.Apps.Entities/Apps/DefaultAppLogStore.cs
  4. 43
      backend/src/Squidex.Infrastructure/Log/BackgroundRequestLogStore.cs
  5. 2
      backend/src/Squidex.Infrastructure/Log/RequestLogStoreOptions.cs
  6. 16
      backend/src/Squidex.Infrastructure/UsageTracking/BackgroundUsageTracker.cs
  7. 37
      backend/tests/Squidex.Infrastructure.Tests/Log/BackgroundRequestLogStoreTests.cs
  8. 26
      backend/tests/Squidex.Infrastructure.Tests/UsageTracking/BackgroundUsageTrackerTests.cs
  9. 6
      backend/tests/docker-compose.yml

119
.github/workflows/dev.yml

@ -12,82 +12,35 @@ on:
- 'release/*'
jobs:
build:
build_test:
runs-on: ubuntu-latest
steps:
- name: Checkout
- name: Prepare - Checkout
uses: actions/checkout@v3.1.0
- name: Inject slug/short variables
- name: Prepare - Inject short Variables
uses: rlespinasse/github-slug-action@v4.3.2
- name: Set up QEMU
- name: Prepare - Set up QEMU
uses: docker/setup-qemu-action@v2.1.0
- name: Set up Docker Buildx
- name: Prepare - Set up Docker Buildx
uses: docker/setup-buildx-action@v2.2.1
- name: Login to Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@v2.1.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: BUILD
if: github.event_name != 'pull_request'
uses: docker/build-push-action@v3.2.0
with:
push: true
build-args: "SQUIDEX__RUNTIME__VERSION=7.0.0-dev-${{ env.BUILD_NUMBER }}"
cache-from: type=gha
cache-to: type=gha,mode=max
tags: squidex/squidex-build
test:
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3.1.0
- name: Inject slug/short variables
uses: rlespinasse/github-slug-action@v4.3.2
- name: Pull from Cache
if: github.event_name != 'pull_request'
run: docker pull squidex/squidex-build
- name: BUILD
if: github.event_name == 'pull_request'
- name: Build - BUILD
uses: docker/build-push-action@v3.2.0
with:
load: true
build-args: "SQUIDEX__RUNTIME__VERSION=7.0.0-dev-${{ env.BUILD_NUMBER }}"
cache-from: type=gha
cache-to: type=gha,mode=max
tags: squidex/squidex-build
- name: Replace Image Name1
uses: mikefarah/yq@v4.28.2
with:
cmd: yq e '.services.squidex1.image = "squidex/squidex-build"' -i backend/tests/docker-compose.yml
- name: Replace Image Name2
uses: mikefarah/yq@v4.28.2
with:
cmd: yq e '.services.squidex2.image = "squidex/squidex-build"' -i backend/tests/docker-compose.yml
tags: squidex-local
- name: Replace Image Name3
uses: mikefarah/yq@v4.28.2
with:
cmd: yq e '.services.squidex3.image = "squidex/squidex-build"' -i backend/tests/docker-compose.yml
- name: Start Test
- name: Test - Start Compose
run: docker-compose up -d
working-directory: backend/tests
- name: RUN TEST
- name: Test - RUN
uses: kohlerdominik/docker-run-action@v1.1.0
with:
image: squidex/build:7
@ -101,7 +54,7 @@ jobs:
volumes: ${{ github.workspace }}:/src
run: dotnet test /src/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj --filter Category!=NotAutomated
- name: RUN TEST on path
- name: Test - RUN on path
uses: kohlerdominik/docker-run-action@v1.1.0
with:
image: squidex/build:7
@ -115,7 +68,7 @@ jobs:
volumes: ${{ github.workspace }}:/src
run: dotnet test /src/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj --filter Category!=NotAutomated
- name: RUN TEST with dedicated collections
- name: Test - RUN with dedicated collections
uses: kohlerdominik/docker-run-action@v1.1.0
with:
image: squidex/build:7
@ -129,54 +82,40 @@ jobs:
volumes: ${{ github.workspace }}:/src
run: dotnet test /src/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj --filter Category!=NotAutomated
- name: Dump docker logs on failure
- name: Test - Dump docker logs on failure
if: failure()
uses: jwalton/gh-docker-logs@v2.2.1
with:
images: 'squidex-tmp,squidex/resizer,squidex/caddy-proxy-path'
images: 'squidex-local,squidex/resizer'
tail: '100'
- name: Cleanup Test
- name: Test - Cleanup
if: always()
run: docker-compose down
working-directory: backend/tests
publish:
needs: test
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
steps:
- name: Checkout
uses: actions/checkout@v3.1.0
- name: Inject slug/short variables
uses: rlespinasse/github-slug-action@v4.3.2
- name: Calculate Version
- name: Publish - Calculate Version
if: github.event_name != 'pull_request'
env:
BUILD_NUMBER: ${{ github.run_number }}
run: |
echo "BUILD_NUMBER=$(($BUILD_NUMBER + 6000))" >> $GITHUB_ENV
- name: Set up QEMU
uses: docker/setup-qemu-action@v2.1.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2.2.1
- name: Login to Docker Hub
- name: Publish - Login to Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@v2.1.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: BUILD
uses: docker/build-push-action@v3.2.0
with:
push: true
build-args: "SQUIDEX__RUNTIME__VERSION=7.0.0-dev-${{ env.BUILD_NUMBER }}"
cache-from: type=gha
cache-to: type=gha,mode=max
tags: |
squidex/squidex:dev
squidex/squidex:dev-${{ env.BUILD_NUMBER }}
- name: Publish - Rename Tags
if: github.event_name != 'pull_request'
run: |
docker tag squidex-local squidex/squidex:dev
docker tag squidex-local squidex/squidex:dev-${{ env.BUILD_NUMBER }}
- name: Publish - Push Tags
if: github.event_name != 'pull_request'
run: |
docker push squidex/squidex:dev
docker push squidex/squidex:dev-${{ env.BUILD_NUMBER }}

155
.github/workflows/release.yml

@ -7,69 +7,35 @@ on:
- "*"
jobs:
build:
build_test:
runs-on: ubuntu-latest
steps:
- name: Checkout
- name: Prepare - Checkout
uses: actions/checkout@v3.1.0
- name: Inject slug/short variables
- name: Prepare - Inject short Variables
uses: rlespinasse/github-slug-action@v4.3.2
- name: Set up QEMU
- name: Prepare - Set up QEMU
uses: docker/setup-qemu-action@v2.1.0
- name: Set up Docker Buildx
- name: Prepare - Set up Docker Buildx
uses: docker/setup-buildx-action@v2.2.1
- name: Login to Docker Hub
uses: docker/login-action@v2.1.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: BUILD
- name: Build - BUILD
uses: docker/build-push-action@v3.2.0
with:
push: true
load: true
build-args: "SQUIDEX__BUILD__VERSION=${{ env.GITHUB_REF_SLUG }},SQUIDEX__RUNTIME__VERSION=${{ env.GITHUB_REF_SLUG }}"
cache-from: type=gha
cache-to: type=gha,mode=max
tags: squidex/squidex-build
test:
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3.1.0
tags: squidex-local
- name: Inject slug/short variables
uses: rlespinasse/github-slug-action@v4.3.2
- name: Pull from Cache
run: docker pull squidex/squidex-build
- name: Replace Image Name1
uses: mikefarah/yq@v4.28.2
with:
cmd: yq e '.services.squidex1.image = "squidex/squidex-build"' -i backend/tests/docker-compose.yml
- name: Replace Image Name2
uses: mikefarah/yq@v4.28.2
with:
cmd: yq e '.services.squidex2.image = "squidex/squidex-build"' -i backend/tests/docker-compose.yml
- name: Replace Image Name3
uses: mikefarah/yq@v4.28.2
with:
cmd: yq e '.services.squidex3.image = "squidex/squidex-build"' -i backend/tests/docker-compose.yml
- name: Start Test
- name: Test - Start Compose
run: docker-compose up -d
working-directory: backend/tests
- name: RUN TEST
- name: Test - RUN
uses: kohlerdominik/docker-run-action@v1.1.0
with:
image: squidex/build:7
@ -83,7 +49,7 @@ jobs:
volumes: ${{ github.workspace }}:/src
run: dotnet test /src/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj --filter Category!=NotAutomated
- name: RUN TEST on path
- name: Test - RUN on path
uses: kohlerdominik/docker-run-action@v1.1.0
with:
image: squidex/build:7
@ -97,7 +63,7 @@ jobs:
volumes: ${{ github.workspace }}:/src
run: dotnet test /src/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj --filter Category!=NotAutomated
- name: RUN TEST with dedicated collections
- name: Test - RUN with dedicated collections
uses: kohlerdominik/docker-run-action@v1.1.0
with:
image: squidex/build:7
@ -111,114 +77,73 @@ jobs:
volumes: ${{ github.workspace }}:/src
run: dotnet test /src/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj --filter Category!=NotAutomated
- name: Dump docker logs on failure
- name: Test - Dump docker logs on failure
if: failure()
uses: jwalton/gh-docker-logs@v2.2.1
with:
images: 'squidex-tmp,squidex/resizer,squidex/caddy-proxy-path'
images: 'squidex-local,squidex/resizer'
tail: '100'
- name: Cleanup Test
- name: Test - Cleanup
if: always()
run: docker-compose down
working-directory: backend/tests
publish:
needs: test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3.1.0
- name: Inject slug/short variables
uses: rlespinasse/github-slug-action@v4.3.2
- name: Get Major Version
- name: Publish - Get Major Version
id: version
uses: rishabhgupta/split-by@v1
with:
string: "${{ env.GITHUB_REF_SLUG }}"
split-by: "."
- name: Check Tag
- name: Publish - Check Tag
id: normal-version
run: |
if [[ ${{ env.GITHUB_REF_SLUG }} =~ ^[0-9]+\.[0-9]+$ ]]; then
echo "STABLE_VERSION=true" >> $GITHUB_ENV
fi
- name: Set up QEMU
uses: docker/setup-qemu-action@v2.1.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2.2.1
- name: Login to Docker Hub
- name: Publish - Login to Docker Hub
uses: docker/login-action@v2.1.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: BUILD
uses: docker/build-push-action@v3.2.0
with:
push: true
build-args: "SQUIDEX__BUILD__VERSION=${{ env.GITHUB_REF_SLUG }},SQUIDEX__RUNTIME__VERSION=${{ env.GITHUB_REF_SLUG }}"
cache-from: type=gha
cache-to: type=gha,mode=max
tags: |
squidex/squidex:latest
squidex/squidex:${{ env.GITHUB_REF_SLUG }}
squidex/squidex:${{ steps.version.outputs._0 }}
- name: Publish - Rename Tags
run: |
docker tag squidex-local squidex/squidex:latest
docker tag squidex-local squidex/squidex:${{ env.GITHUB_REF_SLUG }}
docker tag squidex-local squidex/squidex:${{ steps.version.outputs._0 }}
- name: Publish - Push Tags
if: env.STABLE_VERSION == 'true'
run: |
docker tag squidex-local squidex/squidex:latest
docker tag squidex-local squidex/squidex:${{ env.GITHUB_REF_SLUG }}
docker tag squidex-local squidex/squidex:${{ steps.version.outputs._0 }}
- name: BUILD
uses: docker/build-push-action@v3.2.0
with:
push: true
build-args: "SQUIDEX__BUILD__VERSION=${{ env.GITHUB_REF_SLUG }},SQUIDEX__RUNTIME__VERSION=${{ env.GITHUB_REF_SLUG }}"
cache-from: type=gha
cache-to: type=gha,mode=max
tags: |
squidex/squidex:${{ env.GITHUB_REF_SLUG }}
squidex/squidex:${{ steps.version.outputs._0 }}
if: env.STABLE_VERSION != 'true'
release:
needs: publish
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3.1.0
- name: Inject slug/short variables
uses: rlespinasse/github-slug-action@v4.3.2
- name: Pull from Cache
run: docker pull squidex/squidex-build
- name: Make directories
- name: Release - Make directories
run: sudo mkdir /build /release
- name: Create container
run: docker create --name squidex-container squidex/squidex-build
- name: Release - Create container
run: docker create --name squidex-container squidex-local
- name: Get binaries
- name: Release - Get binaries
run: sudo docker cp squidex-container:/app/. /build
- name: ZIP Binaries
- name: Release - Zip Binaries
run: sudo zip -r /release/binaries.zip .
working-directory: /build
- name: Get Changelog Entry
- name: Release - Get Changelog Entry
id: changelog_reader
uses: mindsers/changelog-reader-action@v2.2.0
uses: mindsers/changelog-reader-action@v2
with:
version: ${{ env.GITHUB_REF_SLUG }}
path: ./CHANGELOG.md
- name: Publish Binaries
uses: ncipollo/release-action@v1.11.1
- name: Release - Publish Binaries
uses: ncipollo/release-action@v1
with:
allowUpdates: true
artifactErrorsFailBuild: true
@ -228,6 +153,6 @@ jobs:
replacesArtifacts: true
token: ${{ secrets.GITHUB_TOKEN }}
- name: Cleanup Binaries
- name: Release - Cleanup Binaries
if: always()
run: docker rm squidex-container
run: docker rm squidex-container

29
backend/src/Squidex.Domain.Apps.Entities/Apps/DefaultAppLogStore.cs

@ -59,8 +59,7 @@ public sealed class DefaultAppLogStore : IAppLogStore, IDeleter
var storedRequest = new Request
{
Key = appId.ToString(),
Timestamp = request.Timestamp
Key = appId.ToString()
};
Append(storedRequest, FieldAuthClientId, request.UserClientId);
@ -76,6 +75,8 @@ public sealed class DefaultAppLogStore : IAppLogStore, IDeleter
Append(storedRequest, FieldRequestPath, request.RequestPath);
Append(storedRequest, FieldStatusCode, request.StatusCode);
storedRequest.Timestamp = request.Timestamp;
return requestLogStore.LogAsync(storedRequest, ct);
}
@ -154,23 +155,31 @@ public sealed class DefaultAppLogStore : IAppLogStore, IDeleter
private static double? GetDouble(Request request, string key)
{
if (request.Properties.TryGetValue(key, out var value) &&
double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
if (!request.Properties.TryGetValue(key, out var value))
{
return null;
}
if (!double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
{
return result;
return null;
}
return null;
return result;
}
private static long? GetLong(Request request, string key)
{
if (request.Properties.TryGetValue(key, out var value) &&
long.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
if (!request.Properties.TryGetValue(key, out var value))
{
return null;
}
if (!long.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
{
return result;
return null;
}
return null;
return result;
}
}

43
backend/src/Squidex.Infrastructure/Log/BackgroundRequestLogStore.cs

@ -16,11 +16,11 @@ public sealed class BackgroundRequestLogStore : DisposableObjectBase, IRequestLo
{
private readonly IRequestLogRepository logRepository;
private readonly ILogger<BackgroundRequestLogStore> log;
private readonly CompletionTimer timer;
private readonly CompletionTimer logTimer;
private readonly RequestLogStoreOptions options;
private ConcurrentQueue<Request> jobs = new ConcurrentQueue<Request>();
private readonly ConcurrentQueue<Request> jobs = new ConcurrentQueue<Request>();
public bool ForceWrite { get; set; }
public int PendingJobs => jobs.Count;
public bool IsEnabled => options.StoreEnabled;
@ -30,8 +30,7 @@ public sealed class BackgroundRequestLogStore : DisposableObjectBase, IRequestLo
this.options = options.Value;
this.logRepository = logRepository;
timer = new CompletionTimer(options.Value.WriteIntervall, TrackAsync, options.Value.WriteIntervall);
this.logTimer = new CompletionTimer(options.Value.WriteIntervall, TrackAsync, options.Value.WriteIntervall);
this.log = log;
}
@ -40,7 +39,7 @@ public sealed class BackgroundRequestLogStore : DisposableObjectBase, IRequestLo
{
if (disposing)
{
timer.StopAsync().Wait();
logTimer.StopAsync().Wait();
}
}
@ -48,7 +47,7 @@ public sealed class BackgroundRequestLogStore : DisposableObjectBase, IRequestLo
{
ThrowIfDisposed();
timer.SkipCurrentDelay();
logTimer.SkipCurrentDelay();
}
private async Task TrackAsync(
@ -59,28 +58,30 @@ public sealed class BackgroundRequestLogStore : DisposableObjectBase, IRequestLo
return;
}
try
if (jobs.IsEmpty)
{
var batchSize = options.BatchSize;
return;
}
var localJobs = Interlocked.Exchange(ref jobs, new ConcurrentQueue<Request>());
try
{
var batch = new List<Request>(options.BatchSize);
if (!localJobs.IsEmpty)
while (jobs.TryDequeue(out var dequeued))
{
var pages = (int)Math.Ceiling((double)localJobs.Count / batchSize);
batch.Add(dequeued);
for (var i = 0; i < pages; i++)
if (batch.Count >= options.BatchSize)
{
var batch = localJobs.Skip(i * batchSize).Take(batchSize);
if (ForceWrite)
{
ct = default;
}
await logRepository.InsertManyAsync(batch, ct);
await logRepository.InsertManyAsync(batch.ToList(), ct);
batch.Clear();
}
}
if (batch.Count > 0)
{
await logRepository.InsertManyAsync(batch, ct);
}
}
catch (Exception ex)
{

2
backend/src/Squidex.Infrastructure/Log/RequestLogStoreOptions.cs

@ -9,7 +9,7 @@ namespace Squidex.Infrastructure.Log;
public sealed class RequestLogStoreOptions
{
public bool StoreEnabled { get; set; }
public bool StoreEnabled { get; set; } = true;
public int StoreRetentionInDays { get; set; } = 90;

16
backend/src/Squidex.Infrastructure/UsageTracking/BackgroundUsageTracker.cs

@ -16,10 +16,10 @@ public sealed class BackgroundUsageTracker : DisposableObjectBase, IUsageTracker
private const int Intervall = 60 * 1000;
private readonly IUsageRepository usageRepository;
private readonly ILogger<BackgroundUsageTracker> log;
private readonly CompletionTimer timer;
private readonly CompletionTimer usageTimer;
private ConcurrentDictionary<(string Key, string Category, DateTime Date), Counters> jobs = new ConcurrentDictionary<(string Key, string Category, DateTime Date), Counters>();
public bool ForceWrite { get; set; }
public int PendingJobs => jobs.Count;
public string FallbackCategory => "*";
@ -27,17 +27,16 @@ public sealed class BackgroundUsageTracker : DisposableObjectBase, IUsageTracker
ILogger<BackgroundUsageTracker> log)
{
this.usageRepository = usageRepository;
this.usageTimer = new CompletionTimer(Intervall, TrackAsync, Intervall);
this.log = log;
timer = new CompletionTimer(Intervall, TrackAsync, Intervall);
}
protected override void DisposeObject(bool disposing)
{
if (disposing)
{
timer.StopAsync().Wait();
usageTimer.StopAsync().Wait();
}
}
@ -45,7 +44,7 @@ public sealed class BackgroundUsageTracker : DisposableObjectBase, IUsageTracker
{
ThrowIfDisposed();
timer.SkipCurrentDelay();
usageTimer.SkipCurrentDelay();
}
private async Task TrackAsync(
@ -75,11 +74,6 @@ public sealed class BackgroundUsageTracker : DisposableObjectBase, IUsageTracker
updateIndex++;
}
if (ForceWrite)
{
ct = default;
}
await usageRepository.TrackUsagesAsync(updates, ct);
}
}

37
backend/tests/Squidex.Infrastructure.Tests/Log/BackgroundRequestLogStoreTests.cs

@ -16,21 +16,14 @@ public class BackgroundRequestLogStoreTests
private readonly CancellationTokenSource cts = new CancellationTokenSource();
private readonly CancellationToken ct;
private readonly IRequestLogRepository requestLogRepository = A.Fake<IRequestLogRepository>();
private readonly RequestLogStoreOptions options = new RequestLogStoreOptions();
private readonly RequestLogStoreOptions options = new RequestLogStoreOptions { StoreEnabled = true };
private readonly BackgroundRequestLogStore sut;
public BackgroundRequestLogStoreTests()
{
ct = cts.Token;
options.StoreEnabled = true;
var log = A.Fake<ILogger<BackgroundRequestLogStore>>();
sut = new BackgroundRequestLogStore(Options.Create(options), requestLogRepository, log)
{
ForceWrite = true
};
sut = new BackgroundRequestLogStore(Options.Create(options), requestLogRepository, A.Fake<ILogger<BackgroundRequestLogStore>>());
}
[Theory]
@ -62,11 +55,7 @@ public class BackgroundRequestLogStoreTests
await sut.LogAsync(new Request { Key = i.ToString(CultureInfo.InvariantCulture) }, ct);
}
sut.Next();
sut.Dispose();
// Wait for the timer to not trigger.
await Task.Delay(500, ct);
await WaitForCompletion();
A.CallTo(() => requestLogRepository.InsertManyAsync(A<IEnumerable<Request>>._, A<CancellationToken>._))
.MustNotHaveHappened();
@ -114,11 +103,7 @@ public class BackgroundRequestLogStoreTests
await sut.LogAsync(new Request { Key = i.ToString(CultureInfo.InvariantCulture) }, ct);
}
sut.Next();
sut.Dispose();
// Wait for the timer to trigger.
await Task.Delay(500, ct);
await WaitForCompletion();
A.CallTo(() => requestLogRepository.InsertManyAsync(Batch("0", "999"), A<CancellationToken>._))
.MustHaveHappened();
@ -130,6 +115,20 @@ public class BackgroundRequestLogStoreTests
.MustHaveHappened();
}
private async Task WaitForCompletion()
{
sut.Next();
using var tcs = new CancellationTokenSource(TimeSpan.FromSeconds(5000));
while (sut.PendingJobs > 0)
{
tcs.Token.ThrowIfCancellationRequested();
await Task.Delay(20, tcs.Token);
}
}
private static IEnumerable<Request> Batch(string from, string to)
{
return A<IEnumerable<Request>>.That.Matches(x => x.First().Key == from && x.Last().Key == to);

26
backend/tests/Squidex.Infrastructure.Tests/UsageTracking/BackgroundUsageTrackerTests.cs

@ -22,12 +22,7 @@ public class BackgroundUsageTrackerTests
{
ct = cts.Token;
var log = A.Fake<ILogger<BackgroundUsageTracker>>();
sut = new BackgroundUsageTracker(usageStore, log)
{
ForceWrite = true
};
sut = new BackgroundUsageTracker(usageStore, A.Fake<ILogger<BackgroundUsageTracker>>());
}
[Fact]
@ -233,11 +228,8 @@ public class BackgroundUsageTrackerTests
updates = args.GetArgument<UsageUpdate[]>(0)!;
});
sut.Next();
sut.Dispose();
// Wait for the timer to trigger.
await Task.Delay(500, ct);
await WaitForCompletion();
updates.Should().BeEquivalentTo(new[]
{
@ -251,6 +243,20 @@ public class BackgroundUsageTrackerTests
.MustHaveHappened();
}
private async Task WaitForCompletion()
{
sut.Next();
using var tcs = new CancellationTokenSource(TimeSpan.FromSeconds(5));
while (sut.PendingJobs > 0)
{
tcs.Token.ThrowIfCancellationRequested();
await Task.Delay(20, tcs.Token);
}
}
private static Counters Counters(double? a = null, double? b = null)
{
var actual = new Counters();

6
backend/tests/docker-compose.yml

@ -8,7 +8,7 @@ services:
- internal
squidex1:
image: squidex
image: squidex-local
environment:
- URLS__BASEURL=http://localhost:8080
- ASSETS__RESIZERURL=http://resizer
@ -33,7 +33,7 @@ services:
- mongo
squidex2:
image: squidex
image: squidex-local
environment:
- URLS__BASEURL=http://localhost:8081/squidex/
- URLS__BASEPATH=squidex/
@ -59,7 +59,7 @@ services:
- mongo
squidex3:
image: squidex
image: squidex-local
environment:
- URLS__BASEURL=http://localhost:8082
- ASSETS__RESIZERURL=http://resizer

Loading…
Cancel
Save