1- using System . IO . Abstractions . TestingHelpers ;
21using Sentry . Internal . Http ;
32
43namespace Sentry . Tests . Internals . Http ;
@@ -644,7 +643,7 @@ public async Task SalvageAbandonedCacheSessions_MovesEnvelopesFromOtherIsolatedD
644643 var baseCacheDir = Directory . GetParent ( currentIsolated ) ! . FullName ;
645644
646645 // Create two abandoned isolated cache directories with envelope files (including in nested folder)
647- string CreateAbandonedDir ( int index )
646+ void CreateAbandonedDir ( int index )
648647 {
649648 var abandoned = Path . Combine ( baseCacheDir , $ "isolated_abandoned_{ index } ") ;
650649 _options . FileSystem . CreateDirectory ( abandoned ) ;
@@ -653,17 +652,10 @@ string CreateAbandonedDir(int index)
653652
654653 // root file
655654 var rootFile = Path . Combine ( abandoned , $ "root_{ index } .envelope") ;
656- if ( _options . FileSystem . CreateFileForWriting ( rootFile , out var s1 ) )
657- {
658- s1 . Dispose ( ) ;
659- }
655+ _options . FileSystem . WriteAllTextToFile ( rootFile , "dummy content" ) ;
660656 // nested file
661657 var nestedFile = Path . Combine ( nested , $ "nested_{ index } .envelope") ;
662- if ( _options . FileSystem . CreateFileForWriting ( nestedFile , out var s2 ) )
663- {
664- s2 . Dispose ( ) ;
665- }
666- return abandoned ;
658+ _options . FileSystem . WriteAllTextToFile ( nestedFile , "dummy content" ) ;
667659 }
668660
669661 CreateAbandonedDir ( 1 ) ;
@@ -699,7 +691,7 @@ public async Task SalvageAbandonedCacheSessions_IgnoresCurrentDirectory()
699691 var currentFile = Path . Combine ( currentIsolated , "current.envelope" ) ;
700692 if ( _options . FileSystem . CreateFileForWriting ( currentFile , out var stream ) )
701693 {
702- stream . Dispose ( ) ;
694+ await stream . DisposeAsync ( ) ;
703695 }
704696 _options . FileSystem . FileExists ( currentFile ) . Should ( ) . BeTrue ( ) ;
705697
@@ -745,4 +737,125 @@ public async Task SalvageAbandonedCacheSessions_SkipsDirectoriesWithActiveLock()
745737 moved . Should ( ) . BeFalse ( ) ;
746738 }
747739 }
740+
741+ [ Fact ]
742+ public async Task MigrateVersion5Cache_MovesEnvelopesFromBaseAndProcessing ( )
743+ {
744+ // Arrange
745+ using var innerTransport = new FakeTransport ( ) ;
746+ await using var transport = CachingTransport . Create ( innerTransport , _options , startWorker : false ) ;
747+
748+ var isolatedCacheDir = _options . GetIsolatedCacheDirectoryPath ( ) ! ;
749+
750+ var baseCacheDir = _options . GetBaseCacheDirectoryPath ( ) ! ;
751+ var rootFile = Path . Combine ( baseCacheDir , "v5_root.envelope" ) ;
752+ _options . FileSystem . CreateDirectory ( baseCacheDir ) ;
753+ _options . FileSystem . WriteAllTextToFile ( rootFile , "dummy content" ) ;
754+
755+ var processingDir = Path . Combine ( baseCacheDir , "__processing" ) ;
756+ var procFile = Path . Combine ( processingDir , "v5_proc.envelope" ) ;
757+ _options . FileSystem . CreateDirectory ( processingDir ) ;
758+ _options . FileSystem . WriteAllTextToFile ( procFile , "dummy content" ) ;
759+
760+ // Act
761+ transport . MigrateVersion5Cache ( CancellationToken . None ) ;
762+
763+ // Assert
764+ var markerFile = Path . Combine ( baseCacheDir , ".migrated" ) ;
765+ _options . FileSystem . FileExists ( markerFile ) . Should ( ) . BeTrue ( ) ;
766+ _options . FileSystem . FileExists ( rootFile ) . Should ( ) . BeFalse ( ) ;
767+ _options . FileSystem . FileExists ( procFile ) . Should ( ) . BeFalse ( ) ;
768+
769+ var movedRoot = Path . Combine ( isolatedCacheDir , "v5_root.envelope" ) ;
770+ var movedProc = Path . Combine ( isolatedCacheDir , "v5_proc.envelope" ) ;
771+ _options . FileSystem . FileExists ( movedRoot ) . Should ( ) . BeTrue ( ) ;
772+ _options . FileSystem . FileExists ( movedProc ) . Should ( ) . BeTrue ( ) ;
773+ }
774+
775+ [ Fact ]
776+ public async Task MigrateVersion5Cache_AlreadyMigrated_Skipped ( )
777+ {
778+ // Arrange
779+ using var innerTransport = new FakeTransport ( ) ;
780+ await using var transport = CachingTransport . Create ( innerTransport , _options , startWorker : false ) ;
781+
782+ var baseCacheDir = _options . GetBaseCacheDirectoryPath ( ) ! ;
783+ var rootFile = Path . Combine ( baseCacheDir , "v5_root.envelope" ) ;
784+ _options . FileSystem . CreateDirectory ( baseCacheDir ) ;
785+ _options . FileSystem . WriteAllTextToFile ( rootFile , "dummy content" ) ;
786+
787+ var processingDir = Path . Combine ( baseCacheDir , "__processing" ) ;
788+ var procFile = Path . Combine ( processingDir , "v5_proc.envelope" ) ;
789+ _options . FileSystem . CreateDirectory ( processingDir ) ;
790+ _options . FileSystem . WriteAllTextToFile ( procFile , "dummy content" ) ;
791+
792+ var marker = Path . Combine ( baseCacheDir , ".migrated" ) ;
793+ _options . FileSystem . WriteAllTextToFile ( marker , "6.0.0" ) ;
794+
795+ // Act
796+ var result = transport . MigrateVersion5Cache ( CancellationToken . None ) ;
797+
798+ // Assert
799+ result . Should ( ) . Be ( CachingTransport . ResultMigrationAlreadyMigrated ) ;
800+ _options . FileSystem . FileExists ( rootFile ) . Should ( ) . BeTrue ( ) ;
801+ _options . FileSystem . FileExists ( procFile ) . Should ( ) . BeTrue ( ) ;
802+ }
803+
804+ [ Fact ]
805+ public async Task MigrateVersion5Cache_MigrationLockHeld_Skipped ( )
806+ {
807+ // Arrange
808+ using var innerTransport = new FakeTransport ( ) ;
809+ await using var transport = CachingTransport . Create ( innerTransport , _options , startWorker : false ) ;
810+
811+ var baseCacheDir = _options . GetBaseCacheDirectoryPath ( ) ! ;
812+ var rootFile = Path . Combine ( baseCacheDir , "v5_root.envelope" ) ;
813+ _options . FileSystem . CreateDirectory ( baseCacheDir ) ;
814+ _options . FileSystem . WriteAllTextToFile ( rootFile , "dummy content" ) ;
815+
816+ var processingDir = Path . Combine ( baseCacheDir , "__processing" ) ;
817+ var procFile = Path . Combine ( processingDir , "v5_proc.envelope" ) ;
818+ _options . FileSystem . CreateDirectory ( processingDir ) ;
819+ _options . FileSystem . WriteAllTextToFile ( procFile , "dummy content" ) ;
820+
821+ var migrationLockPath = Path . Combine ( baseCacheDir , "migration" ) ;
822+ using var coordinator = new CacheDirectoryCoordinator ( migrationLockPath , _options . DiagnosticLogger , _options . FileSystem ) ;
823+ coordinator . TryAcquire ( ) . Should ( ) . BeTrue ( "test must hold the migration lock" ) ;
824+
825+ // Act
826+ var result = transport . MigrateVersion5Cache ( CancellationToken . None ) ;
827+
828+ // Assert
829+ result . Should ( ) . Be ( CachingTransport . ResultMigrationLockNotAcquired ) ;
830+ _options . FileSystem . FileExists ( rootFile ) . Should ( ) . BeTrue ( ) ;
831+ _options . FileSystem . FileExists ( procFile ) . Should ( ) . BeTrue ( ) ;
832+ }
833+
834+ [ Fact ]
835+ public async Task MigrateVersion5Cache_Cancelled_Skipped ( )
836+ {
837+ // Arrange
838+ using var innerTransport = new FakeTransport ( ) ;
839+ await using var transport = CachingTransport . Create ( innerTransport , _options , startWorker : false ) ;
840+
841+ var baseCacheDir = _options . GetBaseCacheDirectoryPath ( ) ! ;
842+ var rootFile = Path . Combine ( baseCacheDir , "v5_root.envelope" ) ;
843+ _options . FileSystem . CreateDirectory ( baseCacheDir ) ;
844+ _options . FileSystem . WriteAllTextToFile ( rootFile , "dummy content" ) ;
845+
846+ var processingDir = Path . Combine ( baseCacheDir , "__processing" ) ;
847+ var procFile = Path . Combine ( processingDir , "v5_proc.envelope" ) ;
848+ _options . FileSystem . CreateDirectory ( processingDir ) ;
849+ _options . FileSystem . WriteAllTextToFile ( procFile , "dummy content" ) ;
850+
851+ // Act
852+ using var cts = new CancellationTokenSource ( ) ;
853+ await cts . CancelAsync ( ) ;
854+ var result = transport . MigrateVersion5Cache ( cts . Token ) ;
855+
856+ // Assert
857+ result . Should ( ) . Be ( CachingTransport . ResultMigrationCancelled ) ;
858+ _options . FileSystem . FileExists ( rootFile ) . Should ( ) . BeTrue ( ) ;
859+ _options . FileSystem . FileExists ( procFile ) . Should ( ) . BeTrue ( ) ;
860+ }
748861}
0 commit comments