diff options
author | Ben Johnson <benbjohnson@yahoo.com> | 2014-05-28 13:31:41 -0600 |
---|---|---|
committer | Ben Johnson <benbjohnson@yahoo.com> | 2014-05-28 13:31:41 -0600 |
commit | 4e31e9d8f94c222d065daa42035aec27959b5624 (patch) | |
tree | a7af0bacb6e97fcdd39406bde69092549c60a07d | |
parent | Merge pull request #178 from benbjohnson/optimize-check (diff) | |
parent | Do not attempt manual transaction rollback in Tx.Copy (diff) | |
download | dedo-4e31e9d8f94c222d065daa42035aec27959b5624.tar.gz dedo-4e31e9d8f94c222d065daa42035aec27959b5624.tar.xz |
Merge pull request #177 from tv42/tx-copy-rollback
Do not attempt manual transaction rollback in Tx.Copy
-rw-r--r-- | tx.go | 3 | ||||
-rw-r--r-- | tx_test.go | 51 |
2 files changed, 51 insertions, 3 deletions
@@ -242,7 +242,6 @@ func (tx *Tx) Copy(w io.Writer) error { // Open reader on the database. f, err := os.OpenFile(tx.db.path, os.O_RDONLY|odirect, 0) if err != nil { - _ = tx.Rollback() return err } @@ -251,14 +250,12 @@ func (tx *Tx) Copy(w io.Writer) error { _, err = io.CopyN(w, f, int64(tx.db.pageSize*2)) tx.db.metalock.Unlock() if err != nil { - _ = tx.Rollback() _ = f.Close() return fmt.Errorf("meta copy: %s", err) } // Copy data pages. if _, err := io.CopyN(w, f, tx.Size()-int64(tx.db.pageSize*2)); err != nil { - _ = tx.Rollback() _ = f.Close() return err } @@ -338,6 +338,57 @@ func TestTx_CopyFile(t *testing.T) { }) } +type failWriterError struct{} + +func (failWriterError) Error() string { + return "error injected for tests" +} + +type failWriter struct { + // fail after this many bytes + After int +} + +func (f *failWriter) Write(p []byte) (n int, err error) { + n = len(p) + if n > f.After { + n = f.After + err = failWriterError{} + } + f.After -= n + return n, err +} + +// Ensure that Copy handles write errors right. +func TestTx_CopyFile_Error_Meta(t *testing.T) { + withOpenDB(func(db *DB, path string) { + db.Update(func(tx *Tx) error { + tx.CreateBucket([]byte("widgets")) + tx.Bucket([]byte("widgets")).Put([]byte("foo"), []byte("bar")) + tx.Bucket([]byte("widgets")).Put([]byte("baz"), []byte("bat")) + return nil + }) + + err := db.View(func(tx *Tx) error { return tx.Copy(&failWriter{}) }) + assert.EqualError(t, err, "meta copy: error injected for tests") + }) +} + +// Ensure that Copy handles write errors right. +func TestTx_CopyFile_Error_Normal(t *testing.T) { + withOpenDB(func(db *DB, path string) { + db.Update(func(tx *Tx) error { + tx.CreateBucket([]byte("widgets")) + tx.Bucket([]byte("widgets")).Put([]byte("foo"), []byte("bar")) + tx.Bucket([]byte("widgets")).Put([]byte("baz"), []byte("bat")) + return nil + }) + + err := db.View(func(tx *Tx) error { return tx.Copy(&failWriter{3 * db.pageSize}) }) + assert.EqualError(t, err, "error injected for tests") + }) +} + func ExampleTx_Rollback() { // Open the database. db, _ := Open(tempfile(), 0666) |