github.phpd.cn/thought-machine/please@v12.2.0+incompatible/tools/jarcat/zip/writer_test.go (about) 1 package zip 2 3 import ( 4 "archive/zip" 5 "bytes" 6 "fmt" 7 "io" 8 "strings" 9 "testing" 10 "time" 11 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 ) 15 16 var expectedModTime = time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC) 17 18 func TestAddZipFile(t *testing.T) { 19 // Have to write an actual file for zip.OpenReader to use later. 20 f := NewFile("add_zip_file_test.zip", false) 21 err := f.AddZipFile("tools/jarcat/zip/test_data/test.zip") 22 require.NoError(t, err) 23 f.Close() 24 assertExpected(t, "add_zip_file_test.zip", 0) 25 } 26 27 // getZipContents is a helper which returns a map of filename -> contents 28 func getZipContents(zipfilePath string) (map[string][]byte, error) { 29 reader, err := zip.OpenReader(zipfilePath) 30 if err != nil { 31 return nil, err 32 } 33 defer reader.Close() 34 res := make(map[string][]byte, len(reader.File)) 35 for _, file := range reader.File { 36 if file.FileInfo().IsDir() { 37 continue 38 } 39 fReader, err := file.Open() 40 if err != nil { 41 return nil, err 42 } 43 defer fReader.Close() 44 contents := make([]byte, file.FileInfo().Size()) 45 if _, err := io.ReadFull(fReader, contents); err != nil { 46 return nil, err 47 } 48 res[file.FileInfo().Name()] = contents 49 } 50 return res, nil 51 } 52 53 func TestAddZipFileConcatenatesSpecialFiles(t *testing.T) { 54 t.Run("Scala Akka reference.conf", func(t *testing.T) { 55 r := require.New(t) 56 f := NewFile("zip_files_with_reference_conf.zip", false) 57 58 err := f.AddZipFile("tools/jarcat/zip/test_data_3/z1.zip") 59 r.NoError(err) 60 err = f.AddZipFile("tools/jarcat/zip/test_data_3/z2.zip") 61 r.NoError(err) 62 f.Close() 63 64 actualContents, err := getZipContents("zip_files_with_reference_conf.zip") 65 r.NoError(err) 66 z1Contents, err := getZipContents("tools/jarcat/zip/test_data_3/z1.zip") 67 r.NoError(err) 68 z2Contents, err := getZipContents("tools/jarcat/zip/test_data_3/z2.zip") 69 r.NoError(err) 70 expectedRefConf := append(z1Contents["reference.conf"], z2Contents["reference.conf"]...) 71 r.EqualValues(actualContents["reference.conf"], expectedRefConf) 72 // OTOH, z2's file1 should just be ignored because it's not a special 73 // case and z1 already added it 74 expectedNormalFile := z1Contents["file1"] 75 r.EqualValues(actualContents["file1"], expectedNormalFile) 76 }) 77 } 78 79 func TestAddFiles(t *testing.T) { 80 f := NewFile("add_files_test.zip", false) 81 f.Suffix = []string{"zip"} 82 err := f.AddFiles("tools/jarcat/zip/test_data") 83 require.NoError(t, err) 84 err = f.AddFiles("tools/jarcat/zip/test_data_2") 85 require.NoError(t, err) 86 f.Close() 87 assertExpected(t, "add_files_test.zip", 0) 88 } 89 90 func assertExpected(t *testing.T, filename string, alignment int) { 91 r, err := zip.OpenReader(filename) 92 require.NoError(t, err) 93 defer r.Close() 94 files := []struct{ Name, Prefix string }{ 95 {"build_step.go", "// Implementation of Step interface."}, 96 {"incrementality.go", "// Utilities to help with incremental builds."}, 97 } 98 for i, f := range r.File { 99 assert.Equal(t, f.Name, files[i].Name) 100 assert.Equal(t, expectedModTime, f.ModTime()) 101 102 fr, err := f.Open() 103 require.NoError(t, err) 104 var buf bytes.Buffer 105 _, err = io.Copy(&buf, fr) 106 require.NoError(t, err) 107 assert.True(t, strings.HasPrefix(buf.String(), files[i].Prefix)) 108 fr.Close() 109 110 if alignment > 0 { 111 offset, err := f.DataOffset() 112 assert.NoError(t, err) 113 assert.True(t, int(offset)%alignment == 0) 114 } 115 } 116 } 117 118 func TestAlignment(t *testing.T) { 119 for _, align := range []int{2, 4, 8, 12, 32} { 120 t.Run(fmt.Sprintf("%dByte", align), func(t *testing.T) { 121 filename := fmt.Sprintf("test_alignment_%d.zip", align) 122 f := NewFile(filename, false) 123 f.Align = align 124 err := f.AddFiles("tools/jarcat/zip/test_data_2") 125 require.NoError(t, err) 126 f.Close() 127 assertExpected(t, filename, align) 128 }) 129 } 130 } 131 132 func TestStoreSuffix(t *testing.T) { 133 // This is a sort of Android-esque example (storing PNGs at 4-byte alignment) 134 f := NewFile("test_store_suffix.zip", false) 135 f.Suffix = []string{"zip"} 136 f.StoreSuffix = []string{"png"} 137 f.Align = 4 138 f.IncludeOther = true 139 err := f.AddFiles("tools/jarcat/zip/test_data") 140 require.NoError(t, err) 141 err = f.AddFiles("tools/jarcat/zip/test_data_2") 142 require.NoError(t, err) 143 f.Close() 144 145 r, err := zip.OpenReader("test_store_suffix.zip") 146 require.NoError(t, err) 147 defer r.Close() 148 assert.Equal(t, 3, len(r.File)) 149 png := r.File[0] 150 assert.Equal(t, "tools/jarcat/zip/test_data/kitten.png", png.Name) 151 assert.Equal(t, zip.Store, png.Method) 152 }