mirror of
https://github.com/kopia/kopia.git
synced 2026-01-02 11:37:54 -05:00
- removed repo.OpenAPIServer() which was only needed for testability - introduced servertesting package to replace it
113 lines
1.7 KiB
Go
113 lines
1.7 KiB
Go
package sparsefile
|
|
|
|
import (
|
|
"bytes"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/kopia/kopia/internal/stat"
|
|
)
|
|
|
|
func TestSparseCopy(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip("sparse files are not supported on windows")
|
|
}
|
|
|
|
dir := t.TempDir()
|
|
|
|
blk, err := stat.GetBlockSize(dir)
|
|
require.NoError(t, err)
|
|
|
|
type chunk struct {
|
|
slice []byte
|
|
off uint64
|
|
rep uint64
|
|
}
|
|
|
|
cases := []struct {
|
|
name string
|
|
size uint64
|
|
data []chunk
|
|
}{
|
|
{
|
|
name: "null",
|
|
size: 0,
|
|
},
|
|
{
|
|
name: "empty",
|
|
size: blk,
|
|
data: []chunk{
|
|
{slice: []byte{0}, off: 0, rep: blk},
|
|
},
|
|
},
|
|
{
|
|
name: "hole",
|
|
size: 2 * blk,
|
|
data: []chunk{
|
|
{slice: []byte{1}, off: blk, rep: blk},
|
|
},
|
|
},
|
|
{
|
|
name: "mix",
|
|
size: 2 * blk,
|
|
data: []chunk{
|
|
{slice: []byte{1}, off: 3, rep: blk - 10},
|
|
{slice: []byte{1}, off: 2*blk - 10, rep: 10},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, c := range cases {
|
|
src := filepath.Join(dir, "src"+c.name)
|
|
dst := filepath.Join(dir, "dst"+c.name)
|
|
|
|
sf, err := os.Create(src)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
for _, d := range c.data {
|
|
sf.WriteAt(bytes.Repeat(d.slice, int(d.rep)), int64(d.off))
|
|
}
|
|
|
|
df, err := os.Create(dst)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err = df.Truncate(int64(c.size)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
blk, err := stat.GetBlockSize(dst)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
_, err = Copy(df, sf, blk)
|
|
if err != nil {
|
|
t.Fatalf("error writing %s: %v", dst, err)
|
|
}
|
|
|
|
s, err := os.ReadFile(src)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
d, err := os.ReadFile(dst)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if !bytes.Equal(s, d) {
|
|
t.Fatalf("contents of %s and %s are not identical", src, dst)
|
|
}
|
|
}
|
|
}
|