Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More robust testing #62

Merged
merged 1 commit into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions src/VahterBanBot.Tests/ContainerTestBase.fs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type VahterTestContainers() =
let mutable publicConnectionString: string = null

// base image for the app, we'll build exactly how we build it in Azure
let buildLogger = StringLogger()
let image =
ImageFromDockerfileBuilder()
.WithDockerfileDirectory(solutionDir, String.Empty)
Expand All @@ -39,6 +40,8 @@ type VahterTestContainers() =
.WithBuildArgument("RESOURCE_REAPER_SESSION_ID", ResourceReaper.DefaultSessionId.ToString("D"))
// it might speed up the process to not clean up the base image
.WithCleanUp(false)
.WithDeleteIfExists(true)
.WithLogger(buildLogger)
.Build()

// private network for the containers
Expand Down Expand Up @@ -113,17 +116,27 @@ type VahterTestContainers() =
.DependsOn(flywayContainer)
.WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(80))
.Build()

let startContainers() = task {
try
// start building the image and spin up db at the same time
let imageTask = image.CreateAsync()
let dbTask = dbContainer.StartAsync()

// wait for both to finish
do! imageTask
do! dbTask
with
| e ->
let logs = buildLogger.ExtractMessages()
let errorMessage = "Container startup failure, logs:\n" + if String.IsNullOrWhiteSpace logs then "<no logs provided>" else logs
raise <| Exception(errorMessage, e)
}

interface IAsyncLifetime with
member this.InitializeAsync() = task {
try
// start building the image and spin up db at the same time
let imageTask = image.CreateAsync()
let dbTask = dbContainer.StartAsync()

// wait for both to finish
do! imageTask
do! dbTask
do! startContainers()
publicConnectionString <- $"Server=127.0.0.1;Database=vahter_bot_ban;Port={dbContainer.GetMappedPublicPort(5432)};User Id=vahter_bot_ban_service;Password=vahter_bot_ban_service;Include Error Detail=true;Minimum Pool Size=1;Maximum Pool Size=20;Max Auto Prepare=100;Auto Prepare Min Usages=1;Trust Server Certificate=true;"

// initialize DB with the schema, database and a DB user
Expand Down Expand Up @@ -158,9 +171,10 @@ type VahterTestContainers() =
httpClient.BaseAddress <- uri
httpClient.DefaultRequestHeaders.Add("X-Telegram-Bot-Api-Secret-Token", "OUR_SECRET")
finally
let struct (_, err) = appContainer.GetLogsAsync().Result
if err <> "" then
failwith err
if appContainer.State <> TestcontainersStates.Undefined then
let struct (_stdout, err) = appContainer.GetLogsAsync().Result
if err <> "" then
failwith err
}
member this.DisposeAsync() = task {
// stop all the containers, flyway might be dead already
Expand Down
16 changes: 16 additions & 0 deletions src/VahterBanBot.Tests/Logging.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace VahterBanBot.Tests

open System
open Microsoft.Extensions.Logging

type StringLogger() =
let lockObj = obj()
let messages = ResizeArray<string>()
interface ILogger with
member this.BeginScope _ = null
member this.IsEnabled _ = true
member this.Log(logLevel, _eventId, state, ex, formatter) =
lock lockObj (fun() ->
messages.Add($"[{logLevel}] {formatter.Invoke(state, ex)}"))

member _.ExtractMessages(): string = lock lockObj (fun() -> String.Join("\n", messages))
1 change: 1 addition & 0 deletions src/VahterBanBot.Tests/VahterBanBot.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<ItemGroup>
<Content Include="test_seed.sql" CopyToOutputDirectory="PreserveNewest" />
<Compile Include="TgMessageUtils.fs" />
<Compile Include="Logging.fs" />
<Compile Include="ContainerTestBase.fs" />
<Compile Include="BaseTests.fs" />
<Compile Include="MessageTests.fs" />
Expand Down