[#222] Add support for aio v1.7.0 in integration tests
All checks were successful
/ DCO (pull_request) Successful in 36s
/ Vulncheck (pull_request) Successful in 1m8s
/ OCI image (pull_request) Successful in 1m20s
/ Builds (pull_request) Successful in 58s
/ Lint (pull_request) Successful in 3m19s
/ Tests (pull_request) Successful in 1m25s
/ Integration tests (pull_request) Successful in 6m56s
All checks were successful
/ DCO (pull_request) Successful in 36s
/ Vulncheck (pull_request) Successful in 1m8s
/ OCI image (pull_request) Successful in 1m20s
/ Builds (pull_request) Successful in 58s
/ Lint (pull_request) Successful in 3m19s
/ Tests (pull_request) Successful in 1m25s
/ Integration tests (pull_request) Successful in 6m56s
Signed-off-by: Aleksey Kravchenko <al.kravchenko@yadro.com>
This commit is contained in:
parent
96a22d98f2
commit
6969be9ac1
3 changed files with 160 additions and 5 deletions
|
@ -10,14 +10,17 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/ape"
|
||||
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/client"
|
||||
|
@ -31,6 +34,8 @@ import (
|
|||
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/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"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
|
@ -51,6 +56,55 @@ const (
|
|||
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) {
|
||||
rootCtx := context.Background()
|
||||
aioImage := "git.frostfs.info/truecloudlab/frostfs-aio:"
|
||||
|
@ -59,6 +113,7 @@ func TestIntegration(t *testing.T) {
|
|||
"1.3.0",
|
||||
"1.5.0",
|
||||
"1.6.5",
|
||||
"1.7.0",
|
||||
}
|
||||
key, err := keys.NewPrivateKeyFromHex("1dd37fba80fec4e6a6f13fd708d8dcb3b29def768017052f6c930fa1c5d90bbb")
|
||||
require.NoError(t, err)
|
||||
|
@ -75,10 +130,16 @@ func TestIntegration(t *testing.T) {
|
|||
ctx, cancel2 := context.WithCancel(rootCtx)
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
createContainer := createContainerWithACL
|
||||
if versionNumber >= versionToUint(t, "1.7.0") {
|
||||
createContainer = createContainerWithAPE
|
||||
}
|
||||
|
||||
// Creating CORS container
|
||||
clientPool := getPool(ctx, t, key)
|
||||
_, err = createContainer(ctx, t, clientPool, ownerID, testCORSContainerName)
|
||||
|
@ -469,15 +530,18 @@ func checkStatusCodes(ctx context.Context, t *testing.T, clientPool *pool.Pool,
|
|||
t.Run("access denied", func(t *testing.T) {
|
||||
basicACL := acl.Private
|
||||
var recs []*eacl.Record
|
||||
var APERules []chain.Rule
|
||||
if version == "1.2.7" {
|
||||
basicACL = acl.PublicRWExtended
|
||||
rec := eacl.NewRecord()
|
||||
rec.SetAction(eacl.ActionDeny)
|
||||
rec.SetOperation(eacl.OperationGet)
|
||||
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)
|
||||
|
||||
key, err := keys.NewPrivateKey()
|
||||
|
@ -560,11 +624,92 @@ func getPool(ctx context.Context, t *testing.T, key *keys.PrivateKey) *pool.Pool
|
|||
return clientPool
|
||||
}
|
||||
|
||||
func createContainer(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)
|
||||
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, 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, acl.PublicRWExtended, publicReadWriteRules(), name)
|
||||
}
|
||||
|
||||
func waitForAPECacheInvalidated(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(),
|
||||
},
|
||||
}
|
||||
|
||||
checkCtxDone := func(ctx context.Context) error {
|
||||
if _, ok := ctx.Deadline(); ok {
|
||||
return fmt.Errorf("waiting time for storing APE chain has expired")
|
||||
}
|
||||
return fmt.Errorf("waiting for the APE chain to be stored has been cancelled")
|
||||
}
|
||||
|
||||
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 contact 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 checkCtxDone(ctx)
|
||||
case <-time.After(8 * time.Second):
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return checkCtxDone(ctx)
|
||||
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 = waitForAPECacheInvalidated(ctx, clientPool, ch, cnrID)
|
||||
}
|
||||
|
||||
func randomString() string {
|
||||
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
b := make([]byte, 8)
|
||||
for i := range b {
|
||||
b[i] = byte('a' + rnd.Intn(26))
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
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
|
||||
err := policy.DecodeString("REP 1")
|
||||
require.NoError(t, err)
|
||||
|
@ -601,6 +746,11 @@ func createContainerBase(ctx context.Context, t *testing.T, clientPool *pool.Poo
|
|||
}
|
||||
fmt.Println(CID.String())
|
||||
|
||||
if len(apeRules) != 0 {
|
||||
chainID := randomString()
|
||||
addAPEChainToContainer(ctx, t, clientPool, chainID, apeRules, CID)
|
||||
}
|
||||
|
||||
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-sdk-go v0.0.0-20250317082814-87bb55f992dc
|
||||
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
|
||||
github.com/bluele/gcache v0.0.2
|
||||
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/hcl v1.0.0 // 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/cpuid/v2 v2.2.6 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // 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/mitchellh/mapstructure v1.5.0 // 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/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/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/go.mod h1:okpbKfVYf/BpejtfFTfhZqFP+sZ8rsHrP8Rr/jYPNRc=
|
||||
git.frostfs.info/TrueCloudLab/tzhash v1.8.0 h1:UFMnUIk0Zh17m8rjGHJMqku2hCgaXDqjqZzS4gsb4UA=
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue