Exemple #1
0
func testCompressDecompress(t *testing.T, size int64, algo AlgorithmType, useReadFrom, useWriteTo bool) {
	// Fake data file is written to disk,
	// as compression reader has to be a ReadSeeker.
	testutil.Remover(t, ZipFilePath)
	data := testutil.CreateDummyBuf(size)
	zipFileDest := openDest(t, ZipFilePath)

	defer testutil.Remover(t, ZipFilePath)

	// Compress.
	w, err := NewWriter(zipFileDest, algo)
	if err != nil {
		t.Errorf("Writer init failed %v", err)
		return

	}

	if _, err := testutil.DumbCopy(w, bytes.NewReader(data), useReadFrom, useWriteTo); err != nil {
		t.Errorf("Compress failed %v", err)
		return
	}

	if err := w.Close(); err != nil {
		t.Errorf("Compression writer close failed: %v", err)
		return
	}

	if err := zipFileDest.Close(); err != nil {
		t.Errorf("close(zipFileDest) failed: %v", err)
		return
	}

	// Read compressed file into buffer.
	dataUncomp := bytes.NewBuffer(nil)
	dataFromZip := openSrc(t, ZipFilePath)

	// Uncompress.
	r := NewReader(dataFromZip)
	if _, err := testutil.DumbCopy(dataUncomp, r, useReadFrom, useWriteTo); err != nil {
		t.Errorf("Decompression failed: %v", err)
		return
	}
	if err := dataFromZip.Close(); err != nil {
		t.Errorf("Zip close failed: %v", err)
		return
	}

	// Compare.
	got, want := dataUncomp.Bytes(), data
	if !bytes.Equal(got, want) {
		t.Error("Uncompressed data and input data does not match.")
		t.Errorf("\tGOT:   %v", util.OmitBytes(got, 10))
		t.Errorf("\tWANT:  %v", util.OmitBytes(want, 10))
		return
	}
}
Exemple #2
0
func testSeek(t *testing.T, N int64, readFrom, writeTo bool) {
	sourceData := testutil.CreateDummyBuf(N)
	source := bytes.NewBuffer(sourceData)
	shared := &bytes.Buffer{}

	t.Logf("Testing seek for size %d", N)

	enc, err := NewWriter(shared, TestKey)
	if err != nil {
		t.Errorf("Creating an encrypted writer failed: %v", err)
		return
	}

	// Encrypt:
	if _, err = testutil.DumbCopy(enc, source, readFrom, writeTo); err != nil {
		t.Errorf("copy(enc, source) failed %v", err)
		return
	}

	// This needs to be here, since close writes
	// left over data to the write stream
	if err = enc.Close(); err != nil {
		t.Errorf("close(enc): %v", err)
		return
	}

	sharedReader := bytes.NewReader(shared.Bytes())
	decLayer, err := NewReader(sharedReader, TestKey)
	if err != nil {
		t.Errorf("creating new reader failed: %v", err)
		return
	}

	lastJump := int64(0)

	for _, test := range SeekTests {
		realOffset := int64(math.Floor(.5 + test.Offset*float64(N)))

		whence := map[int]string{
			0: "SEEK_SET",
			1: "SEEK_CUR",
			2: "SEEK_END",
		}[test.Whence]

		exptOffset := int64(0)
		switch test.Whence {
		case os.SEEK_SET:
			exptOffset = realOffset
		case os.SEEK_CUR:
			exptOffset = lastJump + realOffset
		case os.SEEK_END:
			exptOffset = N + realOffset
		default:
			panic("Bad whence")
		}

		t.Logf(
			" => Seek(%v, %v) -> %v (size: %v)",
			realOffset,
			whence,
			exptOffset,
			N,
		)

		jumpedTo, err := decLayer.Seek(realOffset, test.Whence)
		if err != test.Error {
			if err != io.EOF && N != 0 {
				t.Errorf(
					"Seek(%v, %v) produced an error: %v (should be %v)",
					realOffset,
					whence,
					err,
					test.Error,
				)
			}
			return
		}

		if test.Error != nil {
			continue
		}

		if jumpedTo != exptOffset {
			t.Errorf(
				"Seek(%v, %v) jumped badly. Should be %v, was %v",
				realOffset,
				whence,
				exptOffset,
				jumpedTo,
			)
			return
		}

		lastJump = jumpedTo

		// Decrypt and check if the contents are okay:
		dest := bytes.NewBuffer(nil)

		copiedBytes, err := testutil.DumbCopy(dest, decLayer, readFrom, writeTo)
		if err != nil {
			t.Errorf("Decrypt failed: %v", err)
			return
		}

		if copiedBytes != N-jumpedTo {
			t.Errorf("Copied different amount of decrypted data than expected.")
			t.Errorf("Should be %v, was %v bytes.", N-jumpedTo, copiedBytes)
		}

		// Check the data actually matches the source data.
		if !bytes.Equal(sourceData[jumpedTo:], dest.Bytes()) {
			t.Errorf("Seeked data does not match expectations.")
			t.Errorf("\tEXPECTED: %v", util.OmitBytes(sourceData[jumpedTo:], 10))
			t.Errorf("\tGOT:      %v", util.OmitBytes(dest.Bytes(), 10))
			return
		}

		// Jump back, so the other tests continue to work:
		jumpedAgain, err := decLayer.Seek(jumpedTo, os.SEEK_SET)
		if err != nil {
			t.Errorf("Seeking not possible after reading: %v", err)
			return
		}

		if jumpedTo != jumpedAgain {
			t.Errorf("Jumping back to original pos failed.")
			t.Errorf("Should be %v, was %v.", jumpedTo, jumpedAgain)
			return
		}
	}
}
Exemple #3
0
func testSeek(t *testing.T, size, offset int64, algo AlgorithmType, useReadFrom, useWriteTo bool) {
	// Fake data file is written to disk,
	// as compression reader has to be a ReadSeeker.
	testutil.Remover(t, ZipFilePath)
	data := testutil.CreateDummyBuf(size)
	zipFileDest := openDest(t, ZipFilePath)

	// Compress.
	w, err := NewWriter(zipFileDest, algo)
	if err != nil {
		t.Errorf("Writer init failed %v", err)
		return
	}
	if _, err := testutil.DumbCopy(w, bytes.NewReader(data), useReadFrom, useWriteTo); err != nil {
		t.Errorf("Compress failed %v", err)
		return
	}
	defer testutil.Remover(t, ZipFilePath)

	if err := w.Close(); err != nil {
		t.Errorf("Compression writer close failed: %v", err)
		return
	}

	if err := zipFileDest.Close(); err != nil {
		t.Errorf("close(zipFileDest) failed: %v", err)
		return
	}

	// Read compressed file into buffer.
	dataUncomp := bytes.NewBuffer(nil)
	dataFromZip := openSrc(t, ZipFilePath)
	zr := NewReader(dataFromZip)

	// Set specific offset before read.
	_, err = zr.Seek(offset, os.SEEK_SET)
	if err == io.EOF && offset < size && offset > -1 {
		t.Errorf("Seek failed even with EOF: %d <= %d", offset, size)
		return
	}
	if err != io.EOF && err != nil {
		t.Errorf("Seek failed: %v", err)
		return
	}

	// Read starting at a specific offset.
	if _, err := testutil.DumbCopy(dataUncomp, zr, useReadFrom, useWriteTo); err != nil {
		t.Errorf("Decompression failed: %v", err)
		return
	}
	if err := dataFromZip.Close(); err != nil {
		t.Errorf("Zip close failed: %v", err)
		return
	}

	// Compare.
	maxOffset := offset
	if offset > size {
		maxOffset = size
	}

	if offset < 0 {
		maxOffset = 0
	}

	got, want := dataUncomp.Bytes(), data[maxOffset:]
	if !bytes.Equal(got, want) {
		t.Error("Uncompressed data and input data does not match.")
		t.Errorf("\tGOT:   %v", util.OmitBytes(got, 10))
		t.Errorf("\tWANT:  %v", util.OmitBytes(want, 10))
		return
	}
}
Exemple #4
0
func stageFile(fs *FS, repoPath string, newHash *Hash, key []byte, size uint64, author id.ID) (*File, error) {
	var oldHash *Hash

	file, err := fs.LookupFile(repoPath)
	if err != nil && !IsNoSuchFileError(err) {
		return nil, err
	}

	needRemove := false

	if file != nil {
		// We know this file already.
		log.WithFields(log.Fields{"file": repoPath}).Info("File exists; modifying.")
		oldHash = file.Hash().Clone()
		needRemove = true
	} else {
		par, err := mkdirParents(fs, repoPath)
		if err != nil {
			return nil, err
		}

		// Create a new file at specified path:
		file, err = newEmptyFile(fs, par, path.Base(repoPath))
		if err != nil {
			return nil, err
		}
	}

	log.Infof(
		"store-add: %s (hash: %s, key: %x)",
		repoPath,
		newHash.B58String(),
		util.OmitBytes(file.Key(), 10),
	)

	if file.Hash().Equal(newHash) {
		log.Debugf("Hash was not modified. Refusing update.")
		return nil, ErrNoChange
	}

	parNode, err := file.Parent()
	if err != nil {
		return nil, err
	}

	if parNode == nil {
		return nil, fmt.Errorf("%s has no parent yet (BUG)", repoPath)
	}

	parDir, ok := parNode.(*Directory)
	if !ok {
		return nil, ErrBadNode
	}

	if needRemove {
		// Remove the child before changing the hash:
		if err := parDir.RemoveChild(file); err != nil {
			return nil, err
		}
	}

	file.SetSize(size)
	file.SetModTime(time.Now())
	file.SetKey(key)
	file.SetHash(newHash)

	// Add it again when the hash was changed.
	if err := parDir.Add(file); err != nil {
		return nil, err
	}

	// Create a checkpoint in the version history.
	if err := makeCheckpoint(fs, author, file.ID(), oldHash, newHash, repoPath, repoPath); err != nil {
		return nil, err
	}

	if err := fs.StageNode(file); err != nil {
		return nil, err
	}

	return file, err
}