mirror of
https://github.com/octoleo/restic.git
synced 2024-12-24 20:00:21 +00:00
Merge pull request #748 from restic/fix-747
rest backend: Do not close the reader
This commit is contained in:
commit
d55b56edd3
@ -80,6 +80,10 @@ func (b *restBackend) Save(h restic.Handle, rd io.Reader) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make sure that client.Post() cannot close the reader by wrapping it in
|
||||||
|
// backend.Closer, which has a noop method.
|
||||||
|
rd = backend.Closer{Reader: rd}
|
||||||
|
|
||||||
<-b.connChan
|
<-b.connChan
|
||||||
resp, err := b.client.Post(restPath(b.url, h), "binary/octet-stream", rd)
|
resp, err := b.client.Post(restPath(b.url, h), "binary/octet-stream", rd)
|
||||||
b.connChan <- struct{}{}
|
b.connChan <- struct{}{}
|
||||||
|
@ -6,8 +6,10 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"restic"
|
"restic"
|
||||||
|
"restic/errors"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@ -271,6 +273,16 @@ func TestLoad(t testing.TB) {
|
|||||||
test.OK(t, b.Remove(restic.DataFile, id.String()))
|
test.OK(t, b.Remove(restic.DataFile, id.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type errorCloser struct {
|
||||||
|
io.Reader
|
||||||
|
t testing.TB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec errorCloser) Close() error {
|
||||||
|
ec.t.Error("forbidden method close was called")
|
||||||
|
return errors.New("forbidden method close was called")
|
||||||
|
}
|
||||||
|
|
||||||
// TestSave tests saving data in the backend.
|
// TestSave tests saving data in the backend.
|
||||||
func TestSave(t testing.TB) {
|
func TestSave(t testing.TB) {
|
||||||
b := open(t)
|
b := open(t)
|
||||||
@ -312,6 +324,46 @@ func TestSave(t testing.TB) {
|
|||||||
t.Fatalf("error removing item: %v", err)
|
t.Fatalf("error removing item: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test saving from a tempfile
|
||||||
|
tmpfile, err := ioutil.TempFile("", "restic-backend-save-test-")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
length := rand.Intn(1<<23) + 200000
|
||||||
|
data := test.Random(23, length)
|
||||||
|
copy(id[:], data)
|
||||||
|
|
||||||
|
if _, err = tmpfile.Write(data); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = tmpfile.Seek(0, 0); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
h := restic.Handle{Type: restic.DataFile, Name: id.String()}
|
||||||
|
|
||||||
|
// wrap the tempfile in an errorCloser, so we can detect if the backend
|
||||||
|
// closes the reader
|
||||||
|
err = b.Save(h, errorCloser{t: t, Reader: tmpfile})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = tmpfile.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = os.Remove(tmpfile.Name()); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = b.Remove(h.Type, h.Name)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error removing item: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var filenameTests = []struct {
|
var filenameTests = []struct {
|
||||||
|
@ -29,20 +29,6 @@ type Packer struct {
|
|||||||
tmpfile *os.File
|
tmpfile *os.File
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finalize finalizes the pack.Packer and then closes the tempfile.
|
|
||||||
func (p *Packer) Finalize() (uint, error) {
|
|
||||||
n, err := p.Packer.Finalize()
|
|
||||||
if err != nil {
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = p.tmpfile.Close(); err != nil {
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// packerManager keeps a list of open packs and creates new on demand.
|
// packerManager keeps a list of open packs and creates new on demand.
|
||||||
type packerManager struct {
|
type packerManager struct {
|
||||||
be Saver
|
be Saver
|
||||||
|
@ -47,25 +47,19 @@ func randomID(rd io.Reader) restic.ID {
|
|||||||
|
|
||||||
const maxBlobSize = 1 << 20
|
const maxBlobSize = 1 << 20
|
||||||
|
|
||||||
func saveFile(t testing.TB, be Saver, filename string, id restic.ID) {
|
func saveFile(t testing.TB, be Saver, f *os.File, id restic.ID) {
|
||||||
f, err := os.Open(filename)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
h := restic.Handle{Type: restic.DataFile, Name: id.String()}
|
h := restic.Handle{Type: restic.DataFile, Name: id.String()}
|
||||||
t.Logf("save file %v", h)
|
t.Logf("save file %v", h)
|
||||||
|
|
||||||
if err = be.Save(h, f); err != nil {
|
if err := be.Save(h, f); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = f.Close(); err != nil {
|
if err := f.Close(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = os.Remove(filename)
|
if err := os.Remove(f.Name()); err != nil {
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,8 +98,12 @@ func fillPacks(t testing.TB, rnd *randReader, be Saver, pm *packerManager, buf [
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _, err = packer.tmpfile.Seek(0, 0); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
packID := restic.IDFromHash(packer.hw.Sum(nil))
|
packID := restic.IDFromHash(packer.hw.Sum(nil))
|
||||||
saveFile(t, be, packer.tmpfile.Name(), packID)
|
saveFile(t, be, packer.tmpfile, packID)
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes
|
return bytes
|
||||||
@ -121,7 +119,7 @@ func flushRemainingPacks(t testing.TB, rnd *randReader, be Saver, pm *packerMana
|
|||||||
bytes += int(n)
|
bytes += int(n)
|
||||||
|
|
||||||
packID := restic.IDFromHash(packer.hw.Sum(nil))
|
packID := restic.IDFromHash(packer.hw.Sum(nil))
|
||||||
saveFile(t, be, packer.tmpfile.Name(), packID)
|
saveFile(t, be, packer.tmpfile, packID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ func Random(seed, count int) []byte {
|
|||||||
|
|
||||||
for j := range data {
|
for j := range data {
|
||||||
cur := i + j
|
cur := i + j
|
||||||
if len(p) >= cur {
|
if cur >= len(p) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
p[cur] = data[j]
|
p[cur] = data[j]
|
||||||
|
Loading…
Reference in New Issue
Block a user