github.com/tcnksm/go@v0.0.0-20141208075154-439b32936367/src/archive/zip/writer_test.go (about)

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package zip
     6  
     7  import (
     8  	"bytes"
     9  	"io"
    10  	"io/ioutil"
    11  	"math/rand"
    12  	"os"
    13  	"testing"
    14  )
    15  
    16  // TODO(adg): a more sophisticated test suite
    17  
    18  type WriteTest struct {
    19  	Name   string
    20  	Data   []byte
    21  	Method uint16
    22  	Mode   os.FileMode
    23  }
    24  
    25  var writeTests = []WriteTest{
    26  	{
    27  		Name:   "foo",
    28  		Data:   []byte("Rabbits, guinea pigs, gophers, marsupial rats, and quolls."),
    29  		Method: Store,
    30  		Mode:   0666,
    31  	},
    32  	{
    33  		Name:   "bar",
    34  		Data:   nil, // large data set in the test
    35  		Method: Deflate,
    36  		Mode:   0644,
    37  	},
    38  	{
    39  		Name:   "setuid",
    40  		Data:   []byte("setuid file"),
    41  		Method: Deflate,
    42  		Mode:   0755 | os.ModeSetuid,
    43  	},
    44  	{
    45  		Name:   "setgid",
    46  		Data:   []byte("setgid file"),
    47  		Method: Deflate,
    48  		Mode:   0755 | os.ModeSetgid,
    49  	},
    50  	{
    51  		Name:   "symlink",
    52  		Data:   []byte("../link/target"),
    53  		Method: Deflate,
    54  		Mode:   0755 | os.ModeSymlink,
    55  	},
    56  }
    57  
    58  func TestWriter(t *testing.T) {
    59  	largeData := make([]byte, 1<<17)
    60  	for i := range largeData {
    61  		largeData[i] = byte(rand.Int())
    62  	}
    63  	writeTests[1].Data = largeData
    64  	defer func() {
    65  		writeTests[1].Data = nil
    66  	}()
    67  
    68  	// write a zip file
    69  	buf := new(bytes.Buffer)
    70  	w := NewWriter(buf)
    71  
    72  	for _, wt := range writeTests {
    73  		testCreate(t, w, &wt)
    74  	}
    75  
    76  	if err := w.Close(); err != nil {
    77  		t.Fatal(err)
    78  	}
    79  
    80  	// read it back
    81  	r, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
    82  	if err != nil {
    83  		t.Fatal(err)
    84  	}
    85  	for i, wt := range writeTests {
    86  		testReadFile(t, r.File[i], &wt)
    87  	}
    88  }
    89  
    90  func TestWriterFlush(t *testing.T) {
    91  	var buf bytes.Buffer
    92  	w := NewWriter(struct{ io.Writer }{&buf})
    93  	_, err := w.Create("foo")
    94  	if err != nil {
    95  		t.Fatal(err)
    96  	}
    97  	if buf.Len() > 0 {
    98  		t.Fatalf("Unexpected %d bytes already in buffer", buf.Len())
    99  	}
   100  	if err := w.Flush(); err != nil {
   101  		t.Fatal(err)
   102  	}
   103  	if buf.Len() == 0 {
   104  		t.Fatal("No bytes written after Flush")
   105  	}
   106  }
   107  
   108  func testCreate(t *testing.T, w *Writer, wt *WriteTest) {
   109  	header := &FileHeader{
   110  		Name:   wt.Name,
   111  		Method: wt.Method,
   112  	}
   113  	if wt.Mode != 0 {
   114  		header.SetMode(wt.Mode)
   115  	}
   116  	f, err := w.CreateHeader(header)
   117  	if err != nil {
   118  		t.Fatal(err)
   119  	}
   120  	_, err = f.Write(wt.Data)
   121  	if err != nil {
   122  		t.Fatal(err)
   123  	}
   124  }
   125  
   126  func testReadFile(t *testing.T, f *File, wt *WriteTest) {
   127  	if f.Name != wt.Name {
   128  		t.Fatalf("File name: got %q, want %q", f.Name, wt.Name)
   129  	}
   130  	testFileMode(t, wt.Name, f, wt.Mode)
   131  	rc, err := f.Open()
   132  	if err != nil {
   133  		t.Fatal("opening:", err)
   134  	}
   135  	b, err := ioutil.ReadAll(rc)
   136  	if err != nil {
   137  		t.Fatal("reading:", err)
   138  	}
   139  	err = rc.Close()
   140  	if err != nil {
   141  		t.Fatal("closing:", err)
   142  	}
   143  	if !bytes.Equal(b, wt.Data) {
   144  		t.Errorf("File contents %q, want %q", b, wt.Data)
   145  	}
   146  }
   147  
   148  func BenchmarkCompressedZipGarbage(b *testing.B) {
   149  	b.ReportAllocs()
   150  	var buf bytes.Buffer
   151  	bigBuf := bytes.Repeat([]byte("a"), 1<<20)
   152  	for i := 0; i < b.N; i++ {
   153  		buf.Reset()
   154  		zw := NewWriter(&buf)
   155  		for j := 0; j < 3; j++ {
   156  			w, _ := zw.CreateHeader(&FileHeader{
   157  				Name:   "foo",
   158  				Method: Deflate,
   159  			})
   160  			w.Write(bigBuf)
   161  		}
   162  		zw.Close()
   163  	}
   164  }