Пример #1
0
func TestCopy(t *testing.T) {
	srcb, dstb := new(bytes.Buffer), new(bytes.Buffer)
	for tname, tt := range copyTests() {
		// Reset buffers between tests
		srcb.Reset()
		dstb.Reset()

		// Last file name (needed for gzip.NewReader)
		var fname string

		// Seed the src
		srcw := writer(t, tname, srcb, tt.srcType)
		for _, f := range tt.in {
			srcw.NextFile(f.name, iotest.FileInfo(t, f.contents))
			mustCopy(t, tname, srcw, bytes.NewReader(f.contents))
			fname = f.name
		}
		mustClose(t, tname, srcw)

		// Perform the copy
		srcr := reader(t, tname, srcb, tt.srcType, fname)
		dstw := writer(t, tname, dstb, tt.dstType)
		if err := archive.Copy(dstw, srcr); err != nil {
			t.Fatalf("%s: %v", tname, err)
		}
		srcr.Close() // Read-only
		mustClose(t, tname, dstw)

		// Read back dst to confirm our expectations
		dstr := reader(t, tname, dstb, tt.dstType, fname)
		for _, want := range tt.in {
			buf := new(bytes.Buffer)
			name, err := dstr.NextFile()
			if err != nil {
				t.Fatalf("%s: %v", tname, err)
			}
			mustCopy(t, tname, buf, dstr)
			got := file{
				name:     name,
				contents: buf.Bytes(),
			}

			switch {
			case got.name != want.name:
				t.Errorf("%s: got file %q but want file %q",
					tname, got.name, want.name)

			case !bytes.Equal(got.contents, want.contents):
				t.Errorf("%s: mismatched contents in %q: got %q but want %q",
					tname, got.name, got.contents, want.contents)
			}
		}
		dstr.Close()
	}
}
Пример #2
0
func (rw *rollingFileWriter) archiveUnexplodedLogs(compressionType compressionType, rollsToDelete int, history []string) (err error) {
	closeWithError := func(c io.Closer) {
		if cerr := c.Close(); cerr != nil && err == nil {
			err = cerr
		}
	}

	// Buffer to a temporary file on the same partition
	// Note: archivePath is a path to a file when handling unexploded logs
	dst, err := rw.tempArchiveFile(filepath.Dir(rw.archivePath))
	if err != nil {
		return err
	}
	defer func() {
		closeWithError(dst)
		if err != nil {
			os.Remove(dst.Name()) // Can't do anything when we fail to remove temp file
			return
		}

		// Finalize archive by moving the buffered archive into place
		err = os.Rename(dst.Name(), rw.archivePath)
	}()

	w := compressionType.archiver(dst, false)
	defer closeWithError(w)

	src, err := os.Open(rw.archivePath)
	switch {
	// Archive exists
	case err == nil:
		defer src.Close() // Read-only

		r, err := compressionType.unarchiver(src)
		if err != nil {
			return err
		}
		defer r.Close() // Read-only

		if err := archive.Copy(w, r); err != nil {
			return err
		}

	// Failed to stat
	case !os.IsNotExist(err):
		return err
	}

	// Add new files to the archive
	for i := 0; i < rollsToDelete; i++ {
		rollPath := filepath.Join(rw.currentDirPath, history[i])
		src, err := os.Open(rollPath)
		if err != nil {
			return err
		}
		defer src.Close() // Read-only
		fi, err := src.Stat()
		if err != nil {
			return err
		}
		if err := w.NextFile(src.Name(), fi); err != nil {
			return err
		}
		if _, err := io.Copy(w, src); err != nil {
			return err
		}
	}
	return nil
}