@@ -666,6 +666,132 @@ func makeWriterToTarTest(wt WriterToTar, a fstest.Applier, validate func(string)
666666 }
667667}
668668
669+ func TestDiffTar (t * testing.T ) {
670+ tests := []struct {
671+ name string
672+ validators []tarEntryValidator
673+ a fstest.Applier
674+ b fstest.Applier
675+ }{
676+ {
677+ name : "EmptyDiff" ,
678+ validators : []tarEntryValidator {},
679+ a : fstest .Apply (
680+ fstest .CreateDir ("/etc/" , 0755 ),
681+ ),
682+ b : fstest .Apply (),
683+ },
684+ {
685+ name : "ParentInclusion" ,
686+ validators : []tarEntryValidator {
687+ dirEntry ("d1/" , 0755 ),
688+ dirEntry ("d1/d/" , 0700 ),
689+ dirEntry ("d2/" , 0770 ),
690+ fileEntry ("d2/f" , []byte ("ok" ), 0644 ),
691+ },
692+ a : fstest .Apply (
693+ fstest .CreateDir ("/d1/" , 0755 ),
694+ fstest .CreateDir ("/d2/" , 0770 ),
695+ ),
696+ b : fstest .Apply (
697+ fstest .CreateDir ("/d1/d" , 0700 ),
698+ fstest .CreateFile ("/d2/f" , []byte ("ok" ), 0644 ),
699+ ),
700+ },
701+ }
702+
703+ for _ , at := range tests {
704+ t .Run (at .name , makeDiffTarTest (at .validators , at .a , at .b ))
705+ }
706+ }
707+
708+ type tarEntryValidator func (* tar.Header , []byte ) error
709+
710+ func dirEntry (name string , mode int ) tarEntryValidator {
711+ return func (hdr * tar.Header , b []byte ) error {
712+ if hdr .Typeflag != tar .TypeDir {
713+ return errors .New ("not directory type" )
714+ }
715+ if hdr .Name != name {
716+ return errors .Errorf ("wrong name %q, expected %q" , hdr .Name , name )
717+ }
718+ if hdr .Mode != int64 (mode ) {
719+ return errors .Errorf ("wrong mode %o, expected %o" , hdr .Mode , mode )
720+ }
721+ return nil
722+ }
723+ }
724+
725+ func fileEntry (name string , expected []byte , mode int ) tarEntryValidator {
726+ return func (hdr * tar.Header , b []byte ) error {
727+ if hdr .Typeflag != tar .TypeReg {
728+ return errors .New ("not file type" )
729+ }
730+ if hdr .Name != name {
731+ return errors .Errorf ("wrong name %q, expected %q" , hdr .Name , name )
732+ }
733+ if hdr .Mode != int64 (mode ) {
734+ return errors .Errorf ("wrong mode %o, expected %o" , hdr .Mode , mode )
735+ }
736+ if bytes .Compare (b , expected ) != 0 {
737+ return errors .Errorf ("different file content" )
738+ }
739+ return nil
740+ }
741+ }
742+
743+ func makeDiffTarTest (validators []tarEntryValidator , a , b fstest.Applier ) func (* testing.T ) {
744+ return func (t * testing.T ) {
745+ ad , err := ioutil .TempDir ("" , "test-make-diff-tar-" )
746+ if err != nil {
747+ t .Fatalf ("failed to create temp dir: %v" , err )
748+ }
749+ defer os .RemoveAll (ad )
750+ if err := a .Apply (ad ); err != nil {
751+ t .Fatalf ("failed to apply a: %v" , err )
752+ }
753+
754+ bd , err := ioutil .TempDir ("" , "test-make-diff-tar-" )
755+ if err != nil {
756+ t .Fatalf ("failed to create temp dir: %v" , err )
757+ }
758+ defer os .RemoveAll (bd )
759+ if err := fs .CopyDir (bd , ad ); err != nil {
760+ t .Fatalf ("failed to copy dir: %v" , err )
761+ }
762+ if err := b .Apply (bd ); err != nil {
763+ t .Fatalf ("failed to apply b: %v" , err )
764+ }
765+
766+ rc := Diff (context .Background (), ad , bd )
767+ defer rc .Close ()
768+
769+ tr := tar .NewReader (rc )
770+ for i := 0 ; ; i ++ {
771+ hdr , err := tr .Next ()
772+ if err != nil {
773+ if err == io .EOF {
774+ break
775+ }
776+ t .Fatalf ("tar read error: %v" , err )
777+ }
778+ var b []byte
779+ if hdr .Typeflag == tar .TypeReg && hdr .Size > 0 {
780+ b , err = ioutil .ReadAll (tr )
781+ if err != nil {
782+ t .Fatalf ("tar read file error: %v" , err )
783+ }
784+ }
785+ if i >= len (validators ) {
786+ t .Fatal ("no validator for entry" )
787+ }
788+ if err := validators [i ](hdr , b ); err != nil {
789+ t .Fatalf ("tar entry[%d] validation fail: %#v" , i , err )
790+ }
791+ }
792+ }
793+ }
794+
669795type diffApplier struct {}
670796
671797func (d diffApplier ) TestContext (ctx context.Context ) (context.Context , func (), error ) {
0 commit comments