2
2
mirror of https://github.com/octoleo/restic.git synced 2024-11-29 16:23:59 +00:00

Merge pull request #3974 from greatroar/cleanup

More cleanups and a micro-optimization
This commit is contained in:
Michael Eischer 2022-10-21 21:11:37 +02:00 committed by GitHub
commit c8c8391b21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 68 additions and 63 deletions

View File

@ -217,7 +217,7 @@ func TestTestWalkFiles(t *testing.T) {
return err return err
} }
got[p] = fmt.Sprintf("%v", item) got[p] = fmt.Sprint(item)
return nil return nil
}) })

View File

@ -59,13 +59,14 @@ func (c *Cache) load(h restic.Handle, length int, offset int64) (io.ReadCloser,
return nil, errors.WithStack(err) return nil, errors.WithStack(err)
} }
if fi.Size() <= int64(crypto.CiphertextLength(0)) { size := fi.Size()
if size <= int64(crypto.CiphertextLength(0)) {
_ = f.Close() _ = f.Close()
_ = c.remove(h) _ = c.remove(h)
return nil, errors.Errorf("cached file %v is truncated, removing", h) return nil, errors.Errorf("cached file %v is truncated, removing", h)
} }
if fi.Size() < offset+int64(length) { if size < offset+int64(length) {
_ = f.Close() _ = f.Close()
_ = c.remove(h) _ = c.remove(h)
return nil, errors.Errorf("cached file %v is too small, removing", h) return nil, errors.Errorf("cached file %v is too small, removing", h)

View File

@ -97,7 +97,7 @@ func TestFiles(t *testing.T) {
} }
for _, tpe := range tests { for _, tpe := range tests {
t.Run(fmt.Sprintf("%v", tpe), func(t *testing.T) { t.Run(tpe.String(), func(t *testing.T) {
ids := generateRandomFiles(t, tpe, c) ids := generateRandomFiles(t, tpe, c)
id := randomID(ids) id := randomID(ids)

View File

@ -114,11 +114,7 @@ func (h BlobHandles) Less(i, j int) bool {
continue continue
} }
if b < h[j].ID[k] { return b < h[j].ID[k]
return true
}
return false
} }
return h[i].Type < h[j].Type return h[i].Type < h[j].Type
@ -133,5 +129,5 @@ func (h BlobHandles) String() string {
for _, e := range h { for _, e := range h {
elements = append(elements, e.String()) elements = append(elements, e.String())
} }
return fmt.Sprintf("%v", elements) return fmt.Sprint(elements)
} }

View File

@ -7,18 +7,38 @@ import (
) )
// FileType is the type of a file in the backend. // FileType is the type of a file in the backend.
type FileType string type FileType uint8
// These are the different data types a backend can store. // These are the different data types a backend can store.
const ( const (
PackFile FileType = "data" // use data, as packs are stored under /data in repo PackFile FileType = 1 + iota
KeyFile FileType = "key" KeyFile
LockFile FileType = "lock" LockFile
SnapshotFile FileType = "snapshot" SnapshotFile
IndexFile FileType = "index" IndexFile
ConfigFile FileType = "config" ConfigFile
) )
func (t FileType) String() string {
s := "invalid"
switch t {
case PackFile:
// Spelled "data" instead of "pack" for historical reasons.
s = "data"
case KeyFile:
s = "key"
case LockFile:
s = "lock"
case SnapshotFile:
s = "snapshot"
case IndexFile:
s = "index"
case ConfigFile:
s = "config"
}
return s
}
// Handle is used to store and access data in a backend. // Handle is used to store and access data in a backend.
type Handle struct { type Handle struct {
Type FileType Type FileType
@ -36,10 +56,6 @@ func (h Handle) String() string {
// Valid returns an error if h is not valid. // Valid returns an error if h is not valid.
func (h Handle) Valid() error { func (h Handle) Valid() error {
if h.Type == "" {
return errors.New("type is empty")
}
switch h.Type { switch h.Type {
case PackFile: case PackFile:
case KeyFile: case KeyFile:
@ -48,7 +64,7 @@ func (h Handle) Valid() error {
case IndexFile: case IndexFile:
case ConfigFile: case ConfigFile:
default: default:
return errors.Errorf("invalid Type %q", h.Type) return errors.Errorf("invalid Type %d", h.Type)
} }
if h.Type == ConfigFile { if h.Type == ConfigFile {

View File

@ -1,20 +1,28 @@
package restic package restic
import "testing" import (
"testing"
rtest "github.com/restic/restic/internal/test"
)
func TestHandleString(t *testing.T) {
rtest.Equals(t, "<data/foobar>", Handle{Type: PackFile, Name: "foobar"}.String())
rtest.Equals(t, "<lock/1>", Handle{Type: LockFile, Name: "1"}.String())
}
func TestHandleValid(t *testing.T) {
var handleTests = []struct { var handleTests = []struct {
h Handle h Handle
valid bool valid bool
}{ }{
{Handle{Name: "foo"}, false}, {Handle{Name: "foo"}, false},
{Handle{Type: "foobar"}, false}, {Handle{Type: 0}, false},
{Handle{Type: ConfigFile, Name: ""}, true}, {Handle{Type: ConfigFile, Name: ""}, true},
{Handle{Type: PackFile, Name: ""}, false}, {Handle{Type: PackFile, Name: ""}, false},
{Handle{Type: "", Name: "x"}, false},
{Handle{Type: LockFile, Name: "010203040506"}, true}, {Handle{Type: LockFile, Name: "010203040506"}, true},
} }
func TestHandleValid(t *testing.T) {
for i, test := range handleTests { for i, test := range handleTests {
err := test.h.Valid() err := test.h.Valid()
if err != nil && test.valid { if err != nil && test.valid {

View File

@ -6,8 +6,6 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/restic/restic/internal/errors"
"github.com/minio/sha256-simd" "github.com/minio/sha256-simd"
) )
@ -24,14 +22,13 @@ type ID [idSize]byte
// ParseID converts the given string to an ID. // ParseID converts the given string to an ID.
func ParseID(s string) (ID, error) { func ParseID(s string) (ID, error) {
b, err := hex.DecodeString(s) if len(s) != hex.EncodedLen(idSize) {
return ID{}, fmt.Errorf("invalid length for ID: %q", s)
if err != nil {
return ID{}, errors.Wrap(err, "hex.DecodeString")
} }
if len(b) != idSize { b, err := hex.DecodeString(s)
return ID{}, errors.New("invalid length for hash") if err != nil {
return ID{}, fmt.Errorf("invalid ID: %s", err)
} }
id := ID{} id := ID{}
@ -96,34 +93,21 @@ func (id ID) MarshalJSON() ([]byte, error) {
// UnmarshalJSON parses the JSON-encoded data and stores the result in id. // UnmarshalJSON parses the JSON-encoded data and stores the result in id.
func (id *ID) UnmarshalJSON(b []byte) error { func (id *ID) UnmarshalJSON(b []byte) error {
// check string length // check string length
if len(b) < 2 { if len(b) != len(`""`)+hex.EncodedLen(idSize) {
return fmt.Errorf("invalid ID: %q", b) return fmt.Errorf("invalid length for ID: %q", b)
} }
if len(b)%2 != 0 { if b[0] != '"' {
return fmt.Errorf("invalid ID length: %q", b)
}
// check string delimiters
if b[0] != '"' && b[0] != '\'' {
return fmt.Errorf("invalid start of string: %q", b[0]) return fmt.Errorf("invalid start of string: %q", b[0])
} }
last := len(b) - 1 // Strip JSON string delimiters. The json.Unmarshaler contract says we get
if b[0] != b[last] { // a valid JSON value, so we don't need to check that b[len(b)-1] == '"'.
return fmt.Errorf("starting string delimiter (%q) does not match end (%q)", b[0], b[last]) b = b[1 : len(b)-1]
}
// strip JSON string delimiters
b = b[1:last]
if len(b) != 2*len(id) {
return fmt.Errorf("invalid length for ID")
}
_, err := hex.Decode(id[:], b) _, err := hex.Decode(id[:], b)
if err != nil { if err != nil {
return errors.Wrap(err, "hex.Decode") return fmt.Errorf("invalid ID: %s", err)
} }
return nil return nil

View File

@ -65,5 +65,5 @@ func (ids IDs) String() string {
for _, id := range ids { for _, id := range ids {
elements = append(elements, shortID(id)) elements = append(elements, shortID(id))
} }
return fmt.Sprintf("%v", elements) return fmt.Sprint(elements)
} }

View File

@ -37,7 +37,7 @@ func (TagList) Type() string {
type TagLists []TagList type TagLists []TagList
func (l TagLists) String() string { func (l TagLists) String() string {
return fmt.Sprintf("%v", []TagList(l)) return fmt.Sprint([]TagList(l))
} }
// Flatten returns the list of all tags provided in TagLists // Flatten returns the list of all tags provided in TagLists