@@ -19,6 +19,7 @@ public sealed class UiV2InfrastructureTests : IDisposable
1919 Path . GetTempPath ( ) ,
2020 "CodexSwitchTests" ,
2121 Guid . NewGuid ( ) . ToString ( "N" ) ) ;
22+ private readonly List < UsageLogWriter > _usageLogWriters = [ ] ;
2223
2324 [ Fact ]
2425 public void EnsureValidDefaults_SelectsFirstProvider_WhenActiveProviderIsMissing ( )
@@ -364,7 +365,7 @@ public async Task ProxyHostService_StartAsync_StaysStopped_WhenProxyIsDisabled()
364365 await using var service = new ProxyHostService (
365366 new UsageMeter ( calculator ) ,
366367 calculator ,
367- new UsageLogWriter ( paths ) ,
368+ CreateUsageLogWriter ( paths ) ,
368369 new CodexConfigWriter ( paths ) ,
369370 new ClaudeCodeConfigWriter ( paths ) ,
370371 new ProviderAuthService ( configStore , config , httpClient ) ,
@@ -415,7 +416,7 @@ public async Task ProxyHostService_StopAsync_RestoresBakFiles()
415416 await using var service = new ProxyHostService (
416417 new UsageMeter ( calculator ) ,
417418 calculator ,
418- new UsageLogWriter ( paths ) ,
419+ CreateUsageLogWriter ( paths ) ,
419420 new CodexConfigWriter ( paths ) ,
420421 new ClaudeCodeConfigWriter ( paths ) ,
421422 new ProviderAuthService ( configStore , config , authHttpClient ) ,
@@ -467,7 +468,7 @@ public async Task ProxyHostService_StartAsync_ReusesLocalHealthConnection()
467468 await using var service = new ProxyHostService (
468469 new UsageMeter ( calculator ) ,
469470 calculator ,
470- new UsageLogWriter ( paths ) ,
471+ CreateUsageLogWriter ( paths ) ,
471472 new CodexConfigWriter ( paths ) ,
472473 new ClaudeCodeConfigWriter ( paths ) ,
473474 new ProviderAuthService ( configStore , config , authHttpClient ) ,
@@ -715,7 +716,7 @@ public async Task ProxyHostService_Messages_ProxiesAnthropicDirectRequest()
715716 await using var service = new ProxyHostService (
716717 meter ,
717718 calculator ,
718- new UsageLogWriter ( paths ) ,
719+ CreateUsageLogWriter ( paths ) ,
719720 new CodexConfigWriter ( paths ) ,
720721 new ClaudeCodeConfigWriter ( paths ) ,
721722 new ProviderAuthService ( configStore , config , authHttpClient ) ,
@@ -816,7 +817,7 @@ public async Task ProxyHostService_Messages_ProxiesAnthropicStreamingResponse()
816817 await using var service = new ProxyHostService (
817818 meter ,
818819 calculator ,
819- new UsageLogWriter ( paths ) ,
820+ CreateUsageLogWriter ( paths ) ,
820821 new CodexConfigWriter ( paths ) ,
821822 new ClaudeCodeConfigWriter ( paths ) ,
822823 new ProviderAuthService ( configStore , config , authHttpClient ) ,
@@ -914,7 +915,7 @@ public async Task ProxyHostService_Messages_ConvertsOpenAiChatProviderRequest()
914915 await using var service = new ProxyHostService (
915916 meter ,
916917 calculator ,
917- new UsageLogWriter ( paths ) ,
918+ CreateUsageLogWriter ( paths ) ,
918919 new CodexConfigWriter ( paths ) ,
919920 new ClaudeCodeConfigWriter ( paths ) ,
920921 new ProviderAuthService ( configStore , config , authHttpClient ) ,
@@ -983,7 +984,7 @@ public async Task ProxyHostService_RestartAsync_PublishesStartingWithoutTransien
983984 await using var service = new ProxyHostService (
984985 new UsageMeter ( calculator ) ,
985986 calculator ,
986- new UsageLogWriter ( paths ) ,
987+ CreateUsageLogWriter ( paths ) ,
987988 new CodexConfigWriter ( paths ) ,
988989 new ClaudeCodeConfigWriter ( paths ) ,
989990 new ProviderAuthService ( configStore , config , httpClient ) ,
@@ -1048,7 +1049,7 @@ public async Task ProxyHostService_ReloadConfig_RoutesResponsesToUpdatedActivePr
10481049 await using var service = new ProxyHostService (
10491050 new UsageMeter ( calculator ) ,
10501051 calculator ,
1051- new UsageLogWriter ( paths ) ,
1052+ CreateUsageLogWriter ( paths ) ,
10521053 new CodexConfigWriter ( paths ) ,
10531054 new ClaudeCodeConfigWriter ( paths ) ,
10541055 new ProviderAuthService ( configStore , config , authHttpClient ) ,
@@ -1117,7 +1118,7 @@ public async Task ProxyHostService_ResponsesWebSocket_ProxiesRewrittenPayloadAnd
11171118 await using var service = new ProxyHostService (
11181119 meter ,
11191120 calculator ,
1120- new UsageLogWriter ( paths ) ,
1121+ CreateUsageLogWriter ( paths ) ,
11211122 new CodexConfigWriter ( paths ) ,
11221123 new ClaudeCodeConfigWriter ( paths ) ,
11231124 new ProviderAuthService ( configStore , config , authHttpClient ) ,
@@ -1198,7 +1199,7 @@ public async Task ProxyHostService_ResponsesWebSocket_ReturnsErrorForUnsupported
11981199 await using var service = new ProxyHostService (
11991200 meter ,
12001201 calculator ,
1201- new UsageLogWriter ( paths ) ,
1202+ CreateUsageLogWriter ( paths ) ,
12021203 new CodexConfigWriter ( paths ) ,
12031204 new ClaudeCodeConfigWriter ( paths ) ,
12041205 new ProviderAuthService ( configStore , config , authHttpClient ) ,
@@ -1284,7 +1285,7 @@ public async Task ProxyHostService_ResponsesWebSocket_RetriesOAuthUpstreamConnec
12841285 await using var service = new ProxyHostService (
12851286 meter ,
12861287 calculator ,
1287- new UsageLogWriter ( paths ) ,
1288+ CreateUsageLogWriter ( paths ) ,
12881289 new CodexConfigWriter ( paths ) ,
12891290 new ClaudeCodeConfigWriter ( paths ) ,
12901291 new ProviderAuthService ( new ConfigurationStore ( paths ) , config , authHttpClient ) ,
@@ -1387,7 +1388,7 @@ public void UsageLogItem_FromRecord_ShowsOutputTps()
13871388 public void UsageLogReader_AggregatesRequestsCostAndTokens ( )
13881389 {
13891390 var paths = CreatePaths ( "usage" ) ;
1390- var writer = new UsageLogWriter ( paths ) ;
1391+ var writer = CreateUsageLogWriter ( paths ) ;
13911392 writer . Append ( new UsageLogRecord
13921393 {
13931394 Timestamp = new DateTimeOffset ( 2026 , 5 , 12 , 8 , 15 , 0 , TimeSpan . Zero ) ,
@@ -1450,7 +1451,7 @@ public void UsageLogReader_AggregatesRequestsCostAndTokens()
14501451 public void UsageLogReader_OutputTpsDurationUsesOutputRequestsOnly ( )
14511452 {
14521453 var paths = CreatePaths ( "usage-output-tps" ) ;
1453- var writer = new UsageLogWriter ( paths ) ;
1454+ var writer = CreateUsageLogWriter ( paths ) ;
14541455 var timestamp = new DateTimeOffset ( 2026 , 5 , 12 , 8 , 15 , 0 , TimeSpan . Zero ) ;
14551456 writer . Append ( new UsageLogRecord
14561457 {
@@ -1655,7 +1656,7 @@ public void ProtocolAdapterCommon_ReportOutputActivity_UsesParsedDeltaContent()
16551656 public void UsageLogReader_UsesSelectedRangeAndDailyBuckets ( )
16561657 {
16571658 var paths = CreatePaths ( "usage-range" ) ;
1658- var writer = new UsageLogWriter ( paths ) ;
1659+ var writer = CreateUsageLogWriter ( paths ) ;
16591660 var now = new DateTimeOffset ( 2026 , 5 , 13 , 12 , 0 , 0 , TimeSpan . Zero ) ;
16601661 writer . Append ( new UsageLogRecord
16611662 {
@@ -1707,7 +1708,7 @@ public void UsageLogWriter_WritesDailyPartitionedFiles()
17071708 {
17081709 var paths = CreatePaths ( "usage-partitioned-write" ) ;
17091710 var timestamp = new DateTimeOffset ( 2026 , 5 , 12 , 12 , 0 , 0 , TimeSpan . Zero ) ;
1710- var writer = new UsageLogWriter ( paths ) ;
1711+ var writer = CreateUsageLogWriter ( paths ) ;
17111712
17121713 writer . Append ( new UsageLogRecord
17131714 {
@@ -1738,7 +1739,7 @@ public async Task UsageLogWriter_BufferedAppend_FlushesOnDispose()
17381739 {
17391740 var paths = CreatePaths ( "usage-buffered-write" ) ;
17401741 var timestamp = new DateTimeOffset ( 2026 , 5 , 12 , 12 , 0 , 0 , TimeSpan . Zero ) ;
1741- var writer = new UsageLogWriter ( paths ) ;
1742+ var writer = CreateUsageLogWriter ( paths ) ;
17421743
17431744 writer . AppendBuffered ( new UsageLogRecord
17441745 {
@@ -1786,7 +1787,7 @@ public void UsageLogReader_ReadsPartitionedAndLegacyLogs()
17861787 legacyRecord ,
17871788 new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy . CamelCase } ) + Environment . NewLine ) ;
17881789
1789- var writer = new UsageLogWriter ( paths ) ;
1790+ var writer = CreateUsageLogWriter ( paths ) ;
17901791 writer . Append ( new UsageLogRecord
17911792 {
17921793 Timestamp = now . AddHours ( - 1 ) ,
@@ -1812,7 +1813,7 @@ public void UsageLogReader_ReadsPartitionedAndLegacyLogs()
18121813 public void UsageLogReader_PaginatesRecentRowsWhileKeepingFullTotals ( )
18131814 {
18141815 var paths = CreatePaths ( "usage-recent-limit" ) ;
1815- var writer = new UsageLogWriter ( paths ) ;
1816+ var writer = CreateUsageLogWriter ( paths ) ;
18161817 var now = new DateTimeOffset ( 2026 , 5 , 13 , 12 , 0 , 0 , TimeSpan . Zero ) ;
18171818
18181819 for ( var i = 0 ; i < 100 ; i ++ )
@@ -1856,7 +1857,7 @@ public void UsageLogReader_PaginatesRecentRowsWhileKeepingFullTotals()
18561857 public void UsageLogReader_FiltersBeforeRecentRowLimit ( )
18571858 {
18581859 var paths = CreatePaths ( "usage-filter-limit" ) ;
1859- var writer = new UsageLogWriter ( paths ) ;
1860+ var writer = CreateUsageLogWriter ( paths ) ;
18601861 var now = new DateTimeOffset ( 2026 , 5 , 13 , 12 , 0 , 0 , TimeSpan . Zero ) ;
18611862
18621863 for ( var i = 0 ; i < 80 ; i ++ )
@@ -1914,7 +1915,7 @@ public void UsageLogReader_FiltersBeforeRecentRowLimit()
19141915 public void UsageLogReader_FiltersByClientAppBeforeTotals ( )
19151916 {
19161917 var paths = CreatePaths ( "usage-client-app-filter" ) ;
1917- var writer = new UsageLogWriter ( paths ) ;
1918+ var writer = CreateUsageLogWriter ( paths ) ;
19181919 var now = new DateTimeOffset ( 2026 , 5 , 13 , 12 , 0 , 0 , TimeSpan . Zero ) ;
19191920
19201921 writer . Append ( new UsageLogRecord
@@ -2240,7 +2241,7 @@ public async Task ProviderRequestContext_CodexOAuthHeadersResolveChatGptAccountI
22402241 ActiveProviderId = provider . Id ,
22412242 Providers = { provider }
22422243 } ;
2243- var writer = new UsageLogWriter ( paths ) ;
2244+ var writer = CreateUsageLogWriter ( paths ) ;
22442245 try
22452246 {
22462247 var authService = new ProviderAuthService ( new ConfigurationStore ( paths ) , config , new HttpClient ( ) ) ;
@@ -2420,6 +2421,9 @@ public async Task ProviderUsageQueryService_UsesSelectedOAuthAccountPlaceholders
24202421
24212422 public void Dispose ( )
24222423 {
2424+ foreach ( var writer in _usageLogWriters )
2425+ writer . DisposeAsync ( ) . AsTask ( ) . GetAwaiter ( ) . GetResult ( ) ;
2426+
24232427 if ( Directory . Exists ( _tempDirectory ) )
24242428 Directory . Delete ( _tempDirectory , recursive : true ) ;
24252429 }
@@ -2431,6 +2435,13 @@ private AppPaths CreatePaths(string scenario)
24312435 Path . Combine ( _tempDirectory , scenario , "codex" ) ) ;
24322436 }
24332437
2438+ private UsageLogWriter CreateUsageLogWriter ( AppPaths paths )
2439+ {
2440+ var writer = new UsageLogWriter ( paths ) ;
2441+ _usageLogWriters . Add ( writer ) ;
2442+ return writer ;
2443+ }
2444+
24342445 private static string WriteCodexSession ( AppPaths paths , string relativePath , string modelProvider )
24352446 {
24362447 var path = Path . Combine ( paths . CodexDirectory , relativePath . Replace ( '/' , Path . DirectorySeparatorChar ) ) ;
@@ -2529,7 +2540,7 @@ private static HttpResponseMessage CreateOpenAiResponsesSuccess()
25292540 } ;
25302541 }
25312542
2532- private static ProxyHostService CreateProxyHostService (
2543+ private ProxyHostService CreateProxyHostService (
25332544 AppPaths paths ,
25342545 AppConfig config ,
25352546 UsageMeter meter ,
@@ -2540,7 +2551,7 @@ private static ProxyHostService CreateProxyHostService(
25402551 return new ProxyHostService (
25412552 meter ,
25422553 calculator ,
2543- new UsageLogWriter ( paths ) ,
2554+ CreateUsageLogWriter ( paths ) ,
25442555 new CodexConfigWriter ( paths ) ,
25452556 new ClaudeCodeConfigWriter ( paths ) ,
25462557 new ProviderAuthService ( configStore , config , upstreamHttpClient ) ,
0 commit comments