@@ -242,6 +242,9 @@ var allTests = []func(t *testing.T, sb integration.Sandbox){
242242 testExportLocalNoPlatformSplit ,
243243 testExportLocalNoPlatformSplitOverwrite ,
244244 testExportLocalForcePlatformSplit ,
245+ testExportLocalModeCopyKeepsStaleDestinationFiles ,
246+ testExportLocalModeMirrorRemovesStaleDestinationFiles ,
247+ testExportLocalModeInvalid ,
245248 testSolverOptLocalDirsStillWorks ,
246249 testOCIIndexMediatype ,
247250 testLayerLimitOnMounts ,
@@ -7453,6 +7456,114 @@ func testExportLocalForcePlatformSplit(t *testing.T, sb integration.Sandbox) {
74537456 require .Equal (t , "hello" , string (dt ))
74547457}
74557458
7459+ func testExportLocalModeCopyKeepsStaleDestinationFiles (t * testing.T , sb integration.Sandbox ) {
7460+ c , err := New (sb .Context (), sb .Address ())
7461+ require .NoError (t , err )
7462+ defer c .Close ()
7463+
7464+ st := llb .Scratch ().File (
7465+ llb .Mkfile ("fresh.txt" , 0600 , []byte ("fresh" )),
7466+ )
7467+ def , err := st .Marshal (sb .Context ())
7468+ require .NoError (t , err )
7469+
7470+ destDir := t .TempDir ()
7471+ err = os .WriteFile (filepath .Join (destDir , "stale.txt" ), []byte ("stale" ), 0600 )
7472+ require .NoError (t , err )
7473+ err = os .MkdirAll (filepath .Join (destDir , "stale-dir" ), 0755 )
7474+ require .NoError (t , err )
7475+ err = os .WriteFile (filepath .Join (destDir , "stale-dir" , "old.txt" ), []byte ("stale" ), 0600 )
7476+ require .NoError (t , err )
7477+
7478+ _ , err = c .Solve (sb .Context (), def , SolveOpt {
7479+ Exports : []ExportEntry {
7480+ {
7481+ Type : ExporterLocal ,
7482+ OutputDir : destDir ,
7483+ },
7484+ },
7485+ }, nil )
7486+ require .NoError (t , err )
7487+
7488+ dt , err := os .ReadFile (filepath .Join (destDir , "fresh.txt" ))
7489+ require .NoError (t , err )
7490+ require .Equal (t , "fresh" , string (dt ))
7491+
7492+ _ , err = os .Stat (filepath .Join (destDir , "stale.txt" ))
7493+ require .NoError (t , err )
7494+ _ , err = os .Stat (filepath .Join (destDir , "stale-dir" , "old.txt" ))
7495+ require .NoError (t , err )
7496+ }
7497+
7498+ func testExportLocalModeMirrorRemovesStaleDestinationFiles (t * testing.T , sb integration.Sandbox ) {
7499+ c , err := New (sb .Context (), sb .Address ())
7500+ require .NoError (t , err )
7501+ defer c .Close ()
7502+
7503+ st := llb .Scratch ().File (
7504+ llb .Mkfile ("fresh.txt" , 0600 , []byte ("fresh" )),
7505+ )
7506+ def , err := st .Marshal (sb .Context ())
7507+ require .NoError (t , err )
7508+
7509+ destDir := t .TempDir ()
7510+ err = os .WriteFile (filepath .Join (destDir , "stale.txt" ), []byte ("stale" ), 0600 )
7511+ require .NoError (t , err )
7512+ err = os .MkdirAll (filepath .Join (destDir , "stale-dir" ), 0755 )
7513+ require .NoError (t , err )
7514+ err = os .WriteFile (filepath .Join (destDir , "stale-dir" , "old.txt" ), []byte ("stale" ), 0600 )
7515+ require .NoError (t , err )
7516+
7517+ _ , err = c .Solve (sb .Context (), def , SolveOpt {
7518+ Exports : []ExportEntry {
7519+ {
7520+ Type : ExporterLocal ,
7521+ OutputDir : destDir ,
7522+ Attrs : map [string ]string {
7523+ "mode" : "mirror" ,
7524+ },
7525+ },
7526+ },
7527+ }, nil )
7528+ require .NoError (t , err )
7529+
7530+ dt , err := os .ReadFile (filepath .Join (destDir , "fresh.txt" ))
7531+ require .NoError (t , err )
7532+ require .Equal (t , "fresh" , string (dt ))
7533+
7534+ _ , err = os .Stat (filepath .Join (destDir , "stale.txt" ))
7535+ require .ErrorIs (t , err , os .ErrNotExist )
7536+ _ , err = os .Stat (filepath .Join (destDir , "stale-dir" ))
7537+ require .ErrorIs (t , err , os .ErrNotExist )
7538+ }
7539+
7540+ func testExportLocalModeInvalid (t * testing.T , sb integration.Sandbox ) {
7541+ c , err := New (sb .Context (), sb .Address ())
7542+ require .NoError (t , err )
7543+ defer c .Close ()
7544+
7545+ st := llb .Scratch ().File (
7546+ llb .Mkfile ("fresh.txt" , 0600 , []byte ("fresh" )),
7547+ )
7548+ def , err := st .Marshal (sb .Context ())
7549+ require .NoError (t , err )
7550+
7551+ destDir := t .TempDir ()
7552+ _ , err = c .Solve (sb .Context (), def , SolveOpt {
7553+ Exports : []ExportEntry {
7554+ {
7555+ Type : ExporterLocal ,
7556+ OutputDir : destDir ,
7557+ Attrs : map [string ]string {
7558+ "mode" : "backup" ,
7559+ },
7560+ },
7561+ },
7562+ }, nil )
7563+ require .Error (t , err )
7564+ require .ErrorContains (t , err , `invalid local exporter mode "backup"` )
7565+ }
7566+
74567567func readFileInImage (ctx context.Context , t * testing.T , c * Client , ref , path string ) ([]byte , error ) {
74577568 def , err := llb .Image (ref ).Marshal (ctx )
74587569 if err != nil {
0 commit comments