137 lines
3.5 KiB
Go
137 lines
3.5 KiB
Go
// stm: #unit
|
|
package client
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"embed"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/ipfs/go-blockservice"
|
|
"github.com/ipfs/go-cid"
|
|
"github.com/ipfs/go-datastore"
|
|
dssync "github.com/ipfs/go-datastore/sync"
|
|
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
|
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
|
"github.com/ipfs/go-libipfs/files"
|
|
"github.com/ipfs/go-merkledag"
|
|
unixfile "github.com/ipfs/go-unixfs/file"
|
|
"github.com/ipld/go-car"
|
|
carv2 "github.com/ipld/go-car/v2"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/filecoin-project/lotus/api"
|
|
"github.com/filecoin-project/lotus/markets/storageadapter"
|
|
"github.com/filecoin-project/lotus/node/repo/imports"
|
|
)
|
|
|
|
//go:embed testdata/*
|
|
var testdata embed.FS
|
|
|
|
func TestImportLocal(t *testing.T) {
|
|
// stm: @CLIENT_STORAGE_DEALS_IMPORT_LOCAL_001, @CLIENT_RETRIEVAL_FIND_001
|
|
ds := dssync.MutexWrap(datastore.NewMapDatastore())
|
|
dir := t.TempDir()
|
|
im := imports.NewManager(ds, dir)
|
|
ctx := context.Background()
|
|
|
|
a := &API{
|
|
Imports: im,
|
|
StorageBlockstoreAccessor: storageadapter.NewImportsBlockstoreAccessor(im),
|
|
}
|
|
|
|
b, err := testdata.ReadFile("testdata/payload.txt")
|
|
require.NoError(t, err)
|
|
|
|
// stm: @CLIENT_STORAGE_DEALS_LIST_IMPORTS_001
|
|
root, err := a.ClientImportLocal(ctx, bytes.NewReader(b))
|
|
require.NoError(t, err)
|
|
require.NotEqual(t, cid.Undef, root)
|
|
|
|
list, err := a.ClientListImports(ctx)
|
|
require.NoError(t, err)
|
|
require.Len(t, list, 1)
|
|
|
|
it := list[0]
|
|
require.Equal(t, root, *it.Root)
|
|
require.True(t, strings.HasPrefix(it.CARPath, dir))
|
|
|
|
// stm: @CLIENT_DATA_HAS_LOCAL_001
|
|
local, err := a.ClientHasLocal(ctx, root)
|
|
require.NoError(t, err)
|
|
require.True(t, local)
|
|
|
|
order := api.ExportRef{
|
|
Root: root,
|
|
FromLocalCAR: it.CARPath,
|
|
}
|
|
|
|
// retrieve as UnixFS.
|
|
out1 := filepath.Join(dir, "retrieval1.data") // as unixfs
|
|
out2 := filepath.Join(dir, "retrieval2.data") // as car
|
|
err = a.ClientExport(ctx, order, api.FileRef{
|
|
Path: out1,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
outBytes, err := os.ReadFile(out1)
|
|
require.NoError(t, err)
|
|
require.Equal(t, b, outBytes)
|
|
|
|
err = a.ClientExport(ctx, order, api.FileRef{
|
|
Path: out2,
|
|
IsCAR: true,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// open the CARv2 being custodied by the import manager
|
|
orig, err := carv2.OpenReader(it.CARPath)
|
|
require.NoError(t, err)
|
|
|
|
// open the CARv1 we just exported
|
|
exported, err := carv2.OpenReader(out2)
|
|
require.NoError(t, err)
|
|
|
|
require.EqualValues(t, 1, exported.Version)
|
|
require.EqualValues(t, 2, orig.Version)
|
|
|
|
origRoots, err := orig.Roots()
|
|
require.NoError(t, err)
|
|
require.Len(t, origRoots, 1)
|
|
|
|
exportedRoots, err := exported.Roots()
|
|
require.NoError(t, err)
|
|
require.Len(t, exportedRoots, 1)
|
|
|
|
require.EqualValues(t, origRoots, exportedRoots)
|
|
|
|
// recreate the unixfs dag, and see if it matches the original file byte by byte
|
|
// import the car into a memory blockstore, then export the unixfs file.
|
|
bs := blockstore.NewBlockstore(datastore.NewMapDatastore())
|
|
r, err := exported.DataReader()
|
|
require.NoError(t, err)
|
|
_, err = car.LoadCar(ctx, bs, r)
|
|
require.NoError(t, err)
|
|
|
|
dag := merkledag.NewDAGService(blockservice.New(bs, offline.Exchange(bs)))
|
|
|
|
nd, err := dag.Get(ctx, exportedRoots[0])
|
|
require.NoError(t, err)
|
|
|
|
file, err := unixfile.NewUnixfsFile(ctx, dag, nd)
|
|
require.NoError(t, err)
|
|
|
|
exportedPath := filepath.Join(dir, "exported.data")
|
|
err = files.WriteTo(file, exportedPath)
|
|
require.NoError(t, err)
|
|
|
|
exportedBytes, err := os.ReadFile(exportedPath)
|
|
require.NoError(t, err)
|
|
|
|
// compare original file to recreated unixfs file.
|
|
require.Equal(t, b, exportedBytes)
|
|
}
|