200 lines
5.1 KiB
Go
200 lines
5.1 KiB
Go
package frostfs
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
sdkClient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/pool"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
|
dcontainer "github.com/docker/docker/api/types/container"
|
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
|
"github.com/restic/restic/internal/backend"
|
|
"github.com/restic/restic/internal/restic"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/testcontainers/testcontainers-go"
|
|
"github.com/testcontainers/testcontainers-go/wait"
|
|
)
|
|
|
|
func TestIntegration(t *testing.T) {
|
|
filename := createWallet(t)
|
|
defer func() {
|
|
err := os.Remove(filename)
|
|
require.NoError(t, err)
|
|
}()
|
|
|
|
rootCtx := context.Background()
|
|
aioImage := "truecloudlab/frostfs-aio:"
|
|
versions := []string{
|
|
"1.2.7",
|
|
"1.3.0",
|
|
"1.5.0",
|
|
}
|
|
|
|
cfg := Config{
|
|
Endpoint: "localhost:8080",
|
|
Container: "container",
|
|
Wallet: filename,
|
|
Timeout: 10 * time.Second,
|
|
RebalanceInterval: 20 * time.Second,
|
|
Connections: 1,
|
|
}
|
|
|
|
acc, err := getAccount(cfg)
|
|
require.NoError(t, err)
|
|
|
|
var owner user.ID
|
|
user.IDFromKey(&owner, acc.PrivateKey().PrivateKey.PublicKey)
|
|
|
|
for _, version := range versions {
|
|
ctx, cancel := context.WithCancel(rootCtx)
|
|
aioContainer := createDockerContainer(ctx, t, aioImage+version)
|
|
|
|
p, err := createPool(ctx, acc, cfg)
|
|
require.NoError(t, err)
|
|
_, err = createContainer(ctx, p, owner, cfg.Container, "REP 1")
|
|
require.NoError(t, err)
|
|
|
|
fsBackend, err := Open(ctx, cfg, nil)
|
|
require.NoError(t, err)
|
|
|
|
t.Run("simple store load delete "+version, func(t *testing.T) { simpleStoreLoadDelete(ctx, t, fsBackend) })
|
|
t.Run("list "+version, func(t *testing.T) { simpleList(ctx, t, fsBackend) })
|
|
|
|
err = aioContainer.Terminate(ctx)
|
|
require.NoError(t, err)
|
|
cancel()
|
|
}
|
|
}
|
|
|
|
func simpleStoreLoadDelete(ctx context.Context, t *testing.T, be backend.Backend) {
|
|
h := backend.Handle{
|
|
Type: backend.PackFile,
|
|
IsMetadata: false,
|
|
Name: "some-file",
|
|
}
|
|
|
|
content := []byte("content")
|
|
|
|
err := be.Save(ctx, h, backend.NewByteReader(content, nil))
|
|
require.NoError(t, err)
|
|
|
|
err = be.Load(ctx, h, 0, 0, func(rd io.Reader) error {
|
|
data, err := io.ReadAll(rd)
|
|
require.NoError(t, err)
|
|
require.Equal(t, content, data)
|
|
return nil
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
err = be.Remove(ctx, h)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func simpleList(ctx context.Context, t *testing.T, be backend.Backend) {
|
|
h := backend.Handle{
|
|
Type: backend.PackFile,
|
|
IsMetadata: false,
|
|
Name: "some-file-for-list",
|
|
}
|
|
|
|
content := []byte("content")
|
|
|
|
err := be.Save(ctx, h, backend.NewByteReader(content, nil))
|
|
require.NoError(t, err)
|
|
|
|
var count int
|
|
err = be.List(ctx, restic.PackFile, func(info backend.FileInfo) error {
|
|
count++
|
|
require.Equal(t, h.Name, info.Name)
|
|
return nil
|
|
})
|
|
require.NoError(t, err)
|
|
require.Equal(t, 1, count)
|
|
}
|
|
|
|
func createContainer(ctx context.Context, client *pool.Pool, owner user.ID, containerName, placementPolicy string) (cid.ID, error) {
|
|
var pp netmap.PlacementPolicy
|
|
if err := pp.DecodeString(placementPolicy); err != nil {
|
|
return cid.ID{}, fmt.Errorf("decode policy: %w", err)
|
|
}
|
|
|
|
var cnr container.Container
|
|
cnr.Init()
|
|
cnr.SetPlacementPolicy(pp)
|
|
cnr.SetBasicACL(acl.Private)
|
|
cnr.SetOwner(owner)
|
|
|
|
container.SetName(&cnr, containerName)
|
|
container.SetCreationTime(&cnr, time.Now())
|
|
|
|
wp := &pool.WaitParams{
|
|
PollInterval: 5 * time.Second,
|
|
Timeout: 2 * time.Minute,
|
|
}
|
|
prm := pool.PrmContainerPut{
|
|
ClientParams: sdkClient.PrmContainerPut{
|
|
Container: &cnr,
|
|
},
|
|
WaitParams: wp,
|
|
}
|
|
|
|
containerID, err := client.PutContainer(ctx, prm)
|
|
if err != nil {
|
|
return cid.ID{}, fmt.Errorf("put container: %w", err)
|
|
}
|
|
|
|
return containerID, nil
|
|
}
|
|
|
|
func createWallet(t *testing.T) string {
|
|
file, err := os.CreateTemp("", "wallet")
|
|
require.NoError(t, err)
|
|
err = file.Close()
|
|
require.NoError(t, err)
|
|
|
|
key, err := keys.NewPrivateKeyFromHex("1dd37fba80fec4e6a6f13fd708d8dcb3b29def768017052f6c930fa1c5d90bbb")
|
|
require.NoError(t, err)
|
|
|
|
w, err := wallet.NewWallet(file.Name())
|
|
require.NoError(t, err)
|
|
|
|
acc := wallet.NewAccountFromPrivateKey(key)
|
|
err = acc.Encrypt("", w.Scrypt)
|
|
require.NoError(t, err)
|
|
|
|
w.AddAccount(acc)
|
|
err = w.Save()
|
|
require.NoError(t, err)
|
|
w.Close()
|
|
|
|
return file.Name()
|
|
}
|
|
|
|
func createDockerContainer(ctx context.Context, t *testing.T, image string) testcontainers.Container {
|
|
req := testcontainers.ContainerRequest{
|
|
Image: image,
|
|
WaitingFor: wait.NewLogStrategy("aio container started").WithStartupTimeout(time.Minute),
|
|
Name: "aio",
|
|
Hostname: "aio",
|
|
HostConfigModifier: func(hc *dcontainer.HostConfig) {
|
|
hc.NetworkMode = "host"
|
|
},
|
|
}
|
|
aioC, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
|
|
ContainerRequest: req,
|
|
Started: true,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
return aioC
|
|
}
|