[#222] Add support for aio v1.7.0 in integration tests
All checks were successful
/ DCO (pull_request) Successful in 30s
/ Builds (pull_request) Successful in 1m9s
/ Vulncheck (pull_request) Successful in 1m30s
/ OCI image (pull_request) Successful in 1m36s
/ Lint (pull_request) Successful in 2m53s
/ Tests (pull_request) Successful in 59s
/ Integration tests (pull_request) Successful in 7m38s
All checks were successful
/ DCO (pull_request) Successful in 30s
/ Builds (pull_request) Successful in 1m9s
/ Vulncheck (pull_request) Successful in 1m30s
/ OCI image (pull_request) Successful in 1m36s
/ Lint (pull_request) Successful in 2m53s
/ Tests (pull_request) Successful in 59s
/ Integration tests (pull_request) Successful in 7m38s
Signed-off-by: Aleksey Kravchenko <al.kravchenko@yadro.com>
This commit is contained in:
parent
96a22d98f2
commit
91c2aeead8
3 changed files with 150 additions and 6 deletions
|
@ -14,10 +14,12 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/ape"
|
||||||
containerv2 "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/container"
|
containerv2 "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/container"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||||
|
@ -31,6 +33,8 @@ import (
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/pool"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/pool"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
|
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||||
|
"git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
||||||
docker "github.com/docker/docker/api/types/container"
|
docker "github.com/docker/docker/api/types/container"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||||
|
@ -51,6 +55,58 @@ const (
|
||||||
testCORSContainerName = "cors"
|
testCORSContainerName = "cors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func versionToUint(t *testing.T, v string) uint64 {
|
||||||
|
parts := strings.Split(v, ".")
|
||||||
|
require.Len(t, parts, 3)
|
||||||
|
major, err := strconv.ParseUint(parts[0], 10, 16)
|
||||||
|
require.NoError(t, err)
|
||||||
|
minor, err := strconv.ParseUint(parts[1], 10, 16)
|
||||||
|
require.NoError(t, err)
|
||||||
|
patch, err := strconv.ParseUint(parts[2], 10, 32)
|
||||||
|
require.NoError(t, err)
|
||||||
|
versionNumber := major<<48 | minor<<32 | patch
|
||||||
|
return versionNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
func publicReadWriteRules() []chain.Rule {
|
||||||
|
return []chain.Rule{
|
||||||
|
{
|
||||||
|
Status: chain.Allow,
|
||||||
|
Actions: chain.Actions{
|
||||||
|
Inverted: false,
|
||||||
|
Names: []string{
|
||||||
|
native.MethodPutObject,
|
||||||
|
native.MethodGetObject,
|
||||||
|
native.MethodHeadObject,
|
||||||
|
native.MethodDeleteObject,
|
||||||
|
native.MethodSearchObject,
|
||||||
|
native.MethodRangeObject,
|
||||||
|
native.MethodHashObject,
|
||||||
|
native.MethodPatchObject,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Resources: chain.Resources{
|
||||||
|
Inverted: false,
|
||||||
|
Names: []string{native.ResourceFormatRootObjects},
|
||||||
|
},
|
||||||
|
Any: false},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func privateRules() []chain.Rule {
|
||||||
|
rule := publicReadWriteRules()
|
||||||
|
// The same as public-read-write, except that only the owner is allowed to perform the listed actions
|
||||||
|
rule[0].Condition = []chain.Condition{
|
||||||
|
{
|
||||||
|
Op: chain.CondStringEquals,
|
||||||
|
Kind: chain.KindRequest,
|
||||||
|
Key: native.PropertyKeyActorRole,
|
||||||
|
Value: native.PropertyValueContainerRoleOwner,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return rule
|
||||||
|
}
|
||||||
|
|
||||||
func TestIntegration(t *testing.T) {
|
func TestIntegration(t *testing.T) {
|
||||||
rootCtx := context.Background()
|
rootCtx := context.Background()
|
||||||
aioImage := "git.frostfs.info/truecloudlab/frostfs-aio:"
|
aioImage := "git.frostfs.info/truecloudlab/frostfs-aio:"
|
||||||
|
@ -59,6 +115,7 @@ func TestIntegration(t *testing.T) {
|
||||||
"1.3.0",
|
"1.3.0",
|
||||||
"1.5.0",
|
"1.5.0",
|
||||||
"1.6.5",
|
"1.6.5",
|
||||||
|
"1.7.0",
|
||||||
}
|
}
|
||||||
key, err := keys.NewPrivateKeyFromHex("1dd37fba80fec4e6a6f13fd708d8dcb3b29def768017052f6c930fa1c5d90bbb")
|
key, err := keys.NewPrivateKeyFromHex("1dd37fba80fec4e6a6f13fd708d8dcb3b29def768017052f6c930fa1c5d90bbb")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -75,10 +132,16 @@ func TestIntegration(t *testing.T) {
|
||||||
ctx, cancel2 := context.WithCancel(rootCtx)
|
ctx, cancel2 := context.WithCancel(rootCtx)
|
||||||
|
|
||||||
aioContainer := createDockerContainer(ctx, t, aioImage+version)
|
aioContainer := createDockerContainer(ctx, t, aioImage+version)
|
||||||
if strings.HasPrefix(version, "1.6") {
|
versionNumber := versionToUint(t, version)
|
||||||
|
if versionNumber >= versionToUint(t, "1.6.0") {
|
||||||
registerUser(t, ctx, aioContainer, file.Name())
|
registerUser(t, ctx, aioContainer, file.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createContainer := createContainerWithACL
|
||||||
|
if versionNumber >= versionToUint(t, "1.7.0") {
|
||||||
|
createContainer = createContainerWithAPE
|
||||||
|
}
|
||||||
|
|
||||||
// Creating CORS container
|
// Creating CORS container
|
||||||
clientPool := getPool(ctx, t, key)
|
clientPool := getPool(ctx, t, key)
|
||||||
_, err = createContainer(ctx, t, clientPool, ownerID, testCORSContainerName)
|
_, err = createContainer(ctx, t, clientPool, ownerID, testCORSContainerName)
|
||||||
|
@ -469,15 +532,18 @@ func checkStatusCodes(ctx context.Context, t *testing.T, clientPool *pool.Pool,
|
||||||
t.Run("access denied", func(t *testing.T) {
|
t.Run("access denied", func(t *testing.T) {
|
||||||
basicACL := acl.Private
|
basicACL := acl.Private
|
||||||
var recs []*eacl.Record
|
var recs []*eacl.Record
|
||||||
|
var APERules []chain.Rule
|
||||||
if version == "1.2.7" {
|
if version == "1.2.7" {
|
||||||
basicACL = acl.PublicRWExtended
|
basicACL = acl.PublicRWExtended
|
||||||
rec := eacl.NewRecord()
|
rec := eacl.NewRecord()
|
||||||
rec.SetAction(eacl.ActionDeny)
|
rec.SetAction(eacl.ActionDeny)
|
||||||
rec.SetOperation(eacl.OperationGet)
|
rec.SetOperation(eacl.OperationGet)
|
||||||
recs = append(recs, rec)
|
recs = append(recs, rec)
|
||||||
|
} else if versionToUint(t, version) >= versionToUint(t, "1.7.0") {
|
||||||
|
APERules = privateRules()
|
||||||
}
|
}
|
||||||
|
|
||||||
cnrID, err := createContainerBase(ctx, t, clientPool, ownerID, basicACL, "")
|
cnrID, err := createContainerBase(ctx, t, clientPool, ownerID, basicACL, APERules, "")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
key, err := keys.NewPrivateKey()
|
key, err := keys.NewPrivateKey()
|
||||||
|
@ -560,11 +626,77 @@ func getPool(ctx context.Context, t *testing.T, key *keys.PrivateKey) *pool.Pool
|
||||||
return clientPool
|
return clientPool
|
||||||
}
|
}
|
||||||
|
|
||||||
func createContainer(ctx context.Context, t *testing.T, clientPool *pool.Pool, ownerID user.ID, name string) (cid.ID, error) {
|
func createContainerWithACL(ctx context.Context, t *testing.T, clientPool *pool.Pool, ownerID user.ID, name string) (cid.ID, error) {
|
||||||
return createContainerBase(ctx, t, clientPool, ownerID, acl.PublicRWExtended, name)
|
return createContainerBase(ctx, t, clientPool, ownerID, acl.PublicRWExtended, nil, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createContainerBase(ctx context.Context, t *testing.T, clientPool *pool.Pool, ownerID user.ID, basicACL acl.Basic, name string) (cid.ID, error) {
|
func createContainerWithAPE(ctx context.Context, t *testing.T, clientPool *pool.Pool, ownerID user.ID, name string) (cid.ID, error) {
|
||||||
|
return createContainerBase(ctx, t, clientPool, ownerID, 0, publicReadWriteRules(), name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func waitForAPEBeApplied(ctx context.Context, clientPool *pool.Pool, expectedCh chain.Chain, cnrID cid.ID) error {
|
||||||
|
prmListAPEChains := pool.PrmListAPEChains{
|
||||||
|
Target: ape.ChainTarget{
|
||||||
|
TargetType: ape.TargetTypeContainer,
|
||||||
|
Name: cnrID.EncodeToString(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
for {
|
||||||
|
chains, err := clientPool.ListAPEChains(ctx, prmListAPEChains)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("list APE chains: %w", err)
|
||||||
|
}
|
||||||
|
for _, rawChain := range chains {
|
||||||
|
var ch chain.Chain
|
||||||
|
err = ch.UnmarshalBinary(rawChain.Raw)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unmarshal chain: %w", err)
|
||||||
|
}
|
||||||
|
if bytes.Equal(ch.ID, expectedCh.ID) {
|
||||||
|
// At the moment, according to the core team, there is no way through the API
|
||||||
|
// to check whether the APE chain stored in the contract has been applied to the container.
|
||||||
|
// So after we make sure that the APE chain is stored, we just wait for a certain period of time
|
||||||
|
// (8 seconds by default, the time until the next block and cache invalidation)
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
case <-time.After(8 * time.Second):
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
case <-time.After(500 * time.Millisecond):
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func addAPEChainToContainer(ctx context.Context, t *testing.T, clientPool *pool.Pool, chainID string, rules []chain.Rule, cnrID cid.ID) {
|
||||||
|
ch := chain.Chain{
|
||||||
|
ID: chain.ID(chainID),
|
||||||
|
Rules: rules,
|
||||||
|
}
|
||||||
|
data, err := ch.MarshalBinary()
|
||||||
|
require.NoError(t, err)
|
||||||
|
prmAddAPEChain := pool.PrmAddAPEChain{
|
||||||
|
Target: ape.ChainTarget{
|
||||||
|
TargetType: ape.TargetTypeContainer,
|
||||||
|
Name: cnrID.EncodeToString(),
|
||||||
|
},
|
||||||
|
Chain: ape.Chain{Raw: data},
|
||||||
|
}
|
||||||
|
err = clientPool.AddAPEChain(ctx, prmAddAPEChain)
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = waitForAPEBeApplied(ctx, clientPool, ch, cnrID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createContainerBase(ctx context.Context, t *testing.T, clientPool *pool.Pool, ownerID user.ID, basicACL acl.Basic, apeRules []chain.Rule, name string) (cid.ID, error) {
|
||||||
var policy netmap.PlacementPolicy
|
var policy netmap.PlacementPolicy
|
||||||
err := policy.DecodeString("REP 1")
|
err := policy.DecodeString("REP 1")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -572,7 +704,9 @@ func createContainerBase(ctx context.Context, t *testing.T, clientPool *pool.Poo
|
||||||
var cnr container.Container
|
var cnr container.Container
|
||||||
cnr.Init()
|
cnr.Init()
|
||||||
cnr.SetPlacementPolicy(policy)
|
cnr.SetPlacementPolicy(policy)
|
||||||
cnr.SetBasicACL(basicACL)
|
if basicACL != 0 {
|
||||||
|
cnr.SetBasicACL(basicACL)
|
||||||
|
}
|
||||||
cnr.SetOwner(ownerID)
|
cnr.SetOwner(ownerID)
|
||||||
|
|
||||||
container.SetCreationTime(&cnr, time.Now())
|
container.SetCreationTime(&cnr, time.Now())
|
||||||
|
@ -601,6 +735,11 @@ func createContainerBase(ctx context.Context, t *testing.T, clientPool *pool.Poo
|
||||||
}
|
}
|
||||||
fmt.Println(CID.String())
|
fmt.Println(CID.String())
|
||||||
|
|
||||||
|
if len(apeRules) != 0 {
|
||||||
|
chainID := "http-aio-" + CID.String()[:8]
|
||||||
|
addAPEChainToContainer(ctx, t, clientPool, chainID, apeRules, CID)
|
||||||
|
}
|
||||||
|
|
||||||
return CID, err
|
return CID, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
3
go.mod
3
go.mod
|
@ -8,6 +8,7 @@ require (
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-qos v0.0.0-20250128150313-cfbca7fa1dfe
|
git.frostfs.info/TrueCloudLab/frostfs-qos v0.0.0-20250128150313-cfbca7fa1dfe
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20250317082814-87bb55f992dc
|
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20250317082814-87bb55f992dc
|
||||||
git.frostfs.info/TrueCloudLab/multinet v0.0.0-20241015075604-6cb0d80e0972
|
git.frostfs.info/TrueCloudLab/multinet v0.0.0-20241015075604-6cb0d80e0972
|
||||||
|
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20250425083815-09ff3bf14991
|
||||||
git.frostfs.info/TrueCloudLab/zapjournald v0.0.0-20240124114243-cb2e66427d02
|
git.frostfs.info/TrueCloudLab/zapjournald v0.0.0-20240124114243-cb2e66427d02
|
||||||
github.com/bluele/gcache v0.0.2
|
github.com/bluele/gcache v0.0.2
|
||||||
github.com/docker/docker v27.1.1+incompatible
|
github.com/docker/docker v27.1.1+incompatible
|
||||||
|
@ -68,10 +69,12 @@ require (
|
||||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
github.com/ipfs/go-cid v0.0.7 // indirect
|
github.com/ipfs/go-cid v0.0.7 // indirect
|
||||||
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/klauspost/compress v1.17.4 // indirect
|
github.com/klauspost/compress v1.17.4 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
|
||||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||||
github.com/magiconair/properties v1.8.7 // indirect
|
github.com/magiconair/properties v1.8.7 // indirect
|
||||||
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/minio/sha256-simd v1.0.1 // indirect
|
github.com/minio/sha256-simd v1.0.1 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -52,6 +52,8 @@ git.frostfs.info/TrueCloudLab/hrw v1.2.1 h1:ccBRK21rFvY5R1WotI6LNoPlizk7qSvdfD8l
|
||||||
git.frostfs.info/TrueCloudLab/hrw v1.2.1/go.mod h1:C1Ygde2n843yTZEQ0FP69jYiuaYV0kriLvP4zm8JuvM=
|
git.frostfs.info/TrueCloudLab/hrw v1.2.1/go.mod h1:C1Ygde2n843yTZEQ0FP69jYiuaYV0kriLvP4zm8JuvM=
|
||||||
git.frostfs.info/TrueCloudLab/multinet v0.0.0-20241015075604-6cb0d80e0972 h1:/960fWeyn2AFHwQUwDsWB3sbP6lTEnFnMzLMM6tx6N8=
|
git.frostfs.info/TrueCloudLab/multinet v0.0.0-20241015075604-6cb0d80e0972 h1:/960fWeyn2AFHwQUwDsWB3sbP6lTEnFnMzLMM6tx6N8=
|
||||||
git.frostfs.info/TrueCloudLab/multinet v0.0.0-20241015075604-6cb0d80e0972/go.mod h1:2hM42MBrlhvN6XToaW6OWNk5ZLcu1FhaukGgxtfpDDI=
|
git.frostfs.info/TrueCloudLab/multinet v0.0.0-20241015075604-6cb0d80e0972/go.mod h1:2hM42MBrlhvN6XToaW6OWNk5ZLcu1FhaukGgxtfpDDI=
|
||||||
|
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20250425083815-09ff3bf14991 h1:eTefR8y2y9cg7X5kybIcXDdmABfk/3A2awdmFD3zOsA=
|
||||||
|
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20250425083815-09ff3bf14991/go.mod h1:GZTk55RI4dKzsK6BCn5h2xxE28UHNfgoq/NJxW/LQ6A=
|
||||||
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0 h1:M2KR3iBj7WpY3hP10IevfIB9MURr4O9mwVfJ+SjT3HA=
|
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0 h1:M2KR3iBj7WpY3hP10IevfIB9MURr4O9mwVfJ+SjT3HA=
|
||||||
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0/go.mod h1:okpbKfVYf/BpejtfFTfhZqFP+sZ8rsHrP8Rr/jYPNRc=
|
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0/go.mod h1:okpbKfVYf/BpejtfFTfhZqFP+sZ8rsHrP8Rr/jYPNRc=
|
||||||
git.frostfs.info/TrueCloudLab/tzhash v1.8.0 h1:UFMnUIk0Zh17m8rjGHJMqku2hCgaXDqjqZzS4gsb4UA=
|
git.frostfs.info/TrueCloudLab/tzhash v1.8.0 h1:UFMnUIk0Zh17m8rjGHJMqku2hCgaXDqjqZzS4gsb4UA=
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue