testsuite/ui/uitest: add Edge testing
Change-Id: I1e592ac755b582d4fa73e95fd999a35a27f8a116
This commit is contained in:
parent
96dc43fd49
commit
52c950e429
@ -359,6 +359,7 @@ pipeline {
|
||||
STORJ_TEST_POSTGRES = 'postgres://postgres@localhost/testui?sslmode=disable'
|
||||
STORJ_TEST_BROWSER = '/usr/bin/chromium'
|
||||
STORJ_TEST_SATELLITE_WEB = "${pwd()}/web/satellite"
|
||||
STORJ_TEST_EDGE_HOST = '127.0.0.10'
|
||||
}
|
||||
steps {
|
||||
sh 'psql -U postgres -c \'create database testui;\''
|
||||
|
@ -79,7 +79,7 @@ type Config struct {
|
||||
PartneredSatellites SatList `help:"names and addresses of partnered satellites in JSON list format" default:"[[\"US1\",\"https://us1.storj.io\"],[\"EU1\",\"https://eu1.storj.io\"],[\"AP1\",\"https://ap1.storj.io\"]]"`
|
||||
GeneralRequestURL string `help:"url link to general request page" default:"https://supportdcs.storj.io/hc/en-us/requests/new?ticket_form_id=360000379291"`
|
||||
ProjectLimitsIncreaseRequestURL string `help:"url link to project limit increase request page" default:"https://supportdcs.storj.io/hc/en-us/requests/new?ticket_form_id=360000683212"`
|
||||
GatewayCredentialsRequestURL string `help:"url link for gateway credentials requests" default:"https://auth.us1.storjshare.io"`
|
||||
GatewayCredentialsRequestURL string `help:"url link for gateway credentials requests" default:"https://auth.us1.storjshare.io" devDefault:""`
|
||||
IsBetaSatellite bool `help:"indicates if satellite is in beta" default:"false"`
|
||||
BetaSatelliteFeedbackURL string `help:"url link for for beta satellite feedback" default:""`
|
||||
BetaSatelliteSupportURL string `help:"url link for for beta satellite support" default:""`
|
||||
|
@ -6,8 +6,12 @@ replace storj.io/storj => ../
|
||||
|
||||
require (
|
||||
github.com/go-rod/rod v0.101.8
|
||||
github.com/spacemonkeygo/monkit/v3 v3.0.15
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.7.0
|
||||
go.uber.org/zap v1.17.0
|
||||
storj.io/common v0.0.0-20211011135704-cbe49e9e173e
|
||||
storj.io/gateway-mt v1.14.4-0.20211015103214-01eddbc864fb
|
||||
storj.io/private v0.0.0-20210810102517-434aeab3f17d
|
||||
storj.io/storj v0.12.1-0.20210916114455-b2d724962c24
|
||||
)
|
||||
|
567
testsuite/go.sum
567
testsuite/go.sum
File diff suppressed because it is too large
Load Diff
@ -45,7 +45,8 @@ func Browser(t *testing.T, ctx *testcontext.Context, fn func(*rod.Browser)) {
|
||||
UserDataDir(ctx.Dir("browser")).
|
||||
Logger(zapWriter{Logger: logLauncher}).
|
||||
Set("enable-logging").
|
||||
Set("disable-gpu")
|
||||
Set("disable-gpu").
|
||||
Set("disable-web-security") // TODO: ensure we have proper CORS for testing
|
||||
|
||||
if browserHost := os.Getenv("STORJ_TEST_BROWER_HOSTPORT"); browserHost != "" {
|
||||
host, port, err := net.SplitHostPort(browserHost)
|
||||
|
187
testsuite/ui/uitest/edge.go
Normal file
187
testsuite/ui/uitest/edge.go
Normal file
@ -0,0 +1,187 @@
|
||||
// Copyright (C) 2021 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package uitest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-rod/rod"
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zaptest"
|
||||
|
||||
"storj.io/common/sync2"
|
||||
"storj.io/common/testcontext"
|
||||
"storj.io/gateway-mt/auth"
|
||||
"storj.io/gateway-mt/pkg/authclient"
|
||||
"storj.io/gateway-mt/pkg/server"
|
||||
"storj.io/gateway-mt/pkg/trustedip"
|
||||
"storj.io/private/cfgstruct"
|
||||
"storj.io/storj/cmd/uplink/cmd"
|
||||
"storj.io/storj/private/testplanet"
|
||||
"storj.io/storj/satellite"
|
||||
)
|
||||
|
||||
// EdgePlanet contains defaults for testplanet with Edge.
|
||||
type EdgePlanet struct {
|
||||
*testplanet.Planet
|
||||
|
||||
Gateway struct {
|
||||
AccessKey string
|
||||
SecretKey string
|
||||
|
||||
Addr string
|
||||
}
|
||||
|
||||
Auth struct {
|
||||
Addr string
|
||||
}
|
||||
}
|
||||
|
||||
// EdgeTest defines common args for edge testing.
|
||||
type EdgeTest func(t *testing.T, ctx *testcontext.Context, planet *EdgePlanet, browser *rod.Browser)
|
||||
|
||||
// Edge starts a testplanet together with auth service and gateway.
|
||||
func Edge(t *testing.T, test EdgeTest) {
|
||||
edgehost := os.Getenv("STORJ_TEST_EDGE_HOST")
|
||||
if edgehost == "" {
|
||||
edgehost = "127.0.0.1"
|
||||
}
|
||||
|
||||
// TODO: make address not hardcoded the address selection here may
|
||||
// conflict with some automatically bound address.
|
||||
authSvcAddr := net.JoinHostPort(edgehost, strconv.Itoa(randomRange(20000, 40000)))
|
||||
authSvcAddrTLS := net.JoinHostPort(edgehost, strconv.Itoa(randomRange(20000, 40000)))
|
||||
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1, StorageNodeCount: 4, UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
if dir := os.Getenv("STORJ_TEST_SATELLITE_WEB"); dir != "" {
|
||||
config.Console.StaticDir = dir
|
||||
}
|
||||
config.Console.NewOnboarding = true
|
||||
// TODO: this should be dynamically set from the auth service
|
||||
config.Console.GatewayCredentialsRequestURL = "http://" + authSvcAddr
|
||||
},
|
||||
},
|
||||
NonParallel: true, // Note, do not remove this, because the code above uses same auth service addr.
|
||||
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
||||
access := planet.Uplinks[0].Access[planet.Satellites[0].ID()]
|
||||
|
||||
gwConfig := server.Config{}
|
||||
cfgstruct.Bind(&pflag.FlagSet{}, &gwConfig, cfgstruct.UseTestDefaults())
|
||||
gwConfig.Server.Address = "127.0.0.1:0"
|
||||
gwConfig.AuthURL = "http://" + authSvcAddr
|
||||
gwConfig.InsecureLogAll = true
|
||||
|
||||
authURL, err := url.Parse("http://" + authSvcAddr)
|
||||
require.NoError(t, err)
|
||||
authClient, err := authclient.New(authURL, "super-secret", 5*time.Minute)
|
||||
require.NoError(t, err)
|
||||
|
||||
gateway, err := server.New(gwConfig, zaptest.NewLogger(t).Named("gateway"), nil, trustedip.NewListTrustAll(), []string{}, authClient)
|
||||
require.NoError(t, err)
|
||||
|
||||
defer ctx.Check(gateway.Close)
|
||||
|
||||
authConfig := auth.Config{
|
||||
Endpoint: "http://" + gateway.Address(),
|
||||
AuthToken: "super-secret",
|
||||
KVBackend: "memory://",
|
||||
ListenAddr: authSvcAddr,
|
||||
ListenAddrTLS: authSvcAddrTLS,
|
||||
}
|
||||
for _, sat := range planet.Satellites {
|
||||
authConfig.AllowedSatellites = append(authConfig.AllowedSatellites, sat.NodeURL().String())
|
||||
}
|
||||
|
||||
auth, err := auth.New(ctx, zaptest.NewLogger(t).Named("auth"), authConfig, ctx.Dir("authservice"))
|
||||
require.NoError(t, err)
|
||||
|
||||
defer ctx.Check(auth.Close)
|
||||
ctx.Go(func() error { return auth.Run(ctx) })
|
||||
require.NoError(t, waitForAddress(ctx, authSvcAddr, 3*time.Second))
|
||||
|
||||
ctx.Go(gateway.Run)
|
||||
require.NoError(t, waitForAddress(ctx, gateway.Address(), 3*time.Second))
|
||||
|
||||
// todo: use the unused endpoint below
|
||||
accessKey, secretKey, _, err := cmd.RegisterAccess(ctx, access, "http://"+authSvcAddr, false, 15*time.Second)
|
||||
require.NoError(t, err)
|
||||
|
||||
edge := &EdgePlanet{}
|
||||
edge.Planet = planet
|
||||
edge.Gateway.AccessKey = accessKey
|
||||
edge.Gateway.SecretKey = secretKey
|
||||
edge.Gateway.Addr = gateway.Address()
|
||||
edge.Auth.Addr = authSvcAddr
|
||||
|
||||
Browser(t, ctx, func(browser *rod.Browser) {
|
||||
test(t, ctx, edge, browser)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func randomRange(low, high int) int {
|
||||
// this generates biased crypt random numbers
|
||||
// but it uses crypt/rand to avoid potentially
|
||||
// someone seeding math/rand.
|
||||
span := high - low
|
||||
return low + int(randomUint64()&0x7FFF_FFFF)%span
|
||||
}
|
||||
|
||||
func randomUint64() uint64 {
|
||||
var value [8]byte
|
||||
if _, err := rand.Read(value[:]); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return binary.LittleEndian.Uint64(value[:])
|
||||
}
|
||||
|
||||
// waitForAddress will monitor starting when we are able to start the process.
|
||||
func waitForAddress(ctx context.Context, address string, maxStartupWait time.Duration) error {
|
||||
defer mon.Task()(&ctx)(nil)
|
||||
|
||||
start := time.Now()
|
||||
for time.Since(start) < maxStartupWait {
|
||||
if tryConnect(ctx, address) {
|
||||
return ctx.Err()
|
||||
}
|
||||
|
||||
// wait a bit before retrying to reduce load
|
||||
if !sync2.Sleep(ctx, 50*time.Millisecond) {
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("did not start in required time %v", maxStartupWait)
|
||||
}
|
||||
|
||||
// tryConnect will try to connect to the process public address.
|
||||
func tryConnect(ctx context.Context, address string) bool {
|
||||
defer mon.Task()(&ctx)(nil)
|
||||
|
||||
dialer := net.Dialer{}
|
||||
|
||||
conn, err := dialer.DialContext(ctx, "tcp", address)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
// write empty byte slice to trigger refresh on connection
|
||||
_, _ = conn.Write([]byte{})
|
||||
// ignoring errors, because we only care about being able to connect
|
||||
_ = conn.Close()
|
||||
return true
|
||||
}
|
19
testsuite/ui/uitest/edge_test.go
Normal file
19
testsuite/ui/uitest/edge_test.go
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright (C) 2021 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package uitest_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/go-rod/rod"
|
||||
|
||||
"storj.io/common/testcontext"
|
||||
"storj.io/storj/testsuite/ui/uitest"
|
||||
)
|
||||
|
||||
func TestEdge(t *testing.T) {
|
||||
uitest.Edge(t, func(t *testing.T, ctx *testcontext.Context, planet *uitest.EdgePlanet, browser *rod.Browser) {
|
||||
t.Log("working")
|
||||
})
|
||||
}
|
@ -8,6 +8,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/go-rod/rod"
|
||||
"github.com/spacemonkeygo/monkit/v3"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"storj.io/common/testcontext"
|
||||
@ -15,6 +16,8 @@ import (
|
||||
"storj.io/storj/satellite"
|
||||
)
|
||||
|
||||
var mon = monkit.Package()
|
||||
|
||||
// Test defines common services for uitests.
|
||||
type Test func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet, browser *rod.Browser)
|
||||
|
||||
|
@ -49,7 +49,11 @@ export class ObjectsState {
|
||||
public apiKey = '';
|
||||
public accessGrant = '';
|
||||
public gatewayCredentials: GatewayCredentials = new GatewayCredentials();
|
||||
public s3Client: S3 = new S3({});
|
||||
public s3Client: S3 = new S3({
|
||||
s3ForcePathStyle: true,
|
||||
signatureVersion: "v4",
|
||||
httpOptions: { timeout: 0 },
|
||||
});
|
||||
public bucketsList: Bucket[] = [];
|
||||
public passphrase = '';
|
||||
public fileComponentBucketName = '';
|
||||
@ -88,6 +92,9 @@ export function makeObjectsModule(): StoreModule<ObjectsState, ObjectsContext> {
|
||||
accessKeyId: state.gatewayCredentials.accessKeyId,
|
||||
secretAccessKey: state.gatewayCredentials.secretKey,
|
||||
endpoint: state.gatewayCredentials.endpoint,
|
||||
s3ForcePathStyle: true,
|
||||
signatureVersion: "v4",
|
||||
httpOptions: { timeout: 0 },
|
||||
};
|
||||
|
||||
state.s3Client = new S3(s3Config);
|
||||
@ -109,7 +116,11 @@ export function makeObjectsModule(): StoreModule<ObjectsState, ObjectsContext> {
|
||||
state.passphrase = '';
|
||||
state.accessGrant = '';
|
||||
state.gatewayCredentials = new GatewayCredentials();
|
||||
state.s3Client = new S3({});
|
||||
state.s3Client = new S3({
|
||||
s3ForcePathStyle: true,
|
||||
signatureVersion: "v4",
|
||||
httpOptions: { timeout: 0 },
|
||||
});
|
||||
state.bucketsList = [];
|
||||
state.fileComponentBucketName = '';
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user