381c1e1257
This helps to cleanup the cmd folder a bit. Change-Id: I24025c3dbfd35966325d7d5aaa95cd9a1176a8b7
1189 lines
33 KiB
Go
1189 lines
33 KiB
Go
// Copyright (C) 2021 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
package main_test
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
|
|
pgx "github.com/jackc/pgx/v4"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/zaptest"
|
|
|
|
"storj.io/common/macaroon"
|
|
"storj.io/common/storj"
|
|
"storj.io/common/testcontext"
|
|
"storj.io/common/testrand"
|
|
"storj.io/common/uuid"
|
|
"storj.io/private/dbutil"
|
|
"storj.io/private/dbutil/tempdb"
|
|
migrator "storj.io/storj/cmd/tools/nullify-bad-user-agents"
|
|
"storj.io/storj/satellite"
|
|
"storj.io/storj/satellite/attribution"
|
|
"storj.io/storj/satellite/console"
|
|
"storj.io/storj/satellite/satellitedb/satellitedbtest"
|
|
)
|
|
|
|
// Test no entries in table doesn't error.
|
|
func TestMigrateUsersSelectNoRows(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {}
|
|
test(t, prepare, migrator.MigrateUsers, check, &migrator.Config{
|
|
Limit: 8,
|
|
})
|
|
}
|
|
|
|
// Test no entries in table doesn't error.
|
|
func TestMigrateUsersLimitedSelectNoRows(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {}
|
|
test(t, prepare, migrator.MigrateUsersLimited, check, &migrator.Config{
|
|
MaxUpdates: 1,
|
|
})
|
|
}
|
|
|
|
// Test no rows to update returns no error.
|
|
func TestMigrateUsersUpdateNoRows(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
userAgent := []byte("teststorj")
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
|
|
_, err := db.Console().Users().Insert(ctx, &console.User{
|
|
ID: testrand.UUID(),
|
|
Email: "test@storj.test",
|
|
FullName: "Test Test",
|
|
PasswordHash: []byte{0, 1, 2, 3},
|
|
UserAgent: userAgent,
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
_, users, err := db.Console().Users().GetByEmailWithUnverified(ctx, "test@storj.test")
|
|
require.NoError(t, err)
|
|
require.Len(t, users, 1)
|
|
require.Equal(t, userAgent, users[0].UserAgent)
|
|
}
|
|
test(t, prepare, migrator.MigrateUsers, check, &migrator.Config{
|
|
Limit: 8,
|
|
})
|
|
}
|
|
|
|
// Test select offset beyond final row.
|
|
// With only one row, selecting with an offset of 1 will return 0 rows.
|
|
// Test that this is accounted for and updates the row correctly.
|
|
func TestMigrateUsersSelectOffsetBeyondRowCount(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
userID := testrand.UUID()
|
|
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
_, err := db.Console().Users().Insert(ctx, &console.User{
|
|
ID: userID,
|
|
Email: "test@storj.test",
|
|
FullName: "Test Test",
|
|
PasswordHash: []byte{0, 1, 2, 3},
|
|
PartnerID: userID,
|
|
UserAgent: userID.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
user, err := db.Console().Users().Get(ctx, userID)
|
|
require.NoError(t, err)
|
|
require.Nil(t, user.UserAgent)
|
|
}
|
|
test(t, prepare, migrator.MigrateUsers, check, &migrator.Config{
|
|
Limit: 8,
|
|
})
|
|
}
|
|
|
|
// Test user_agent field is updated correctly.
|
|
func TestMigrateUsers(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
var n int
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
// insert with user_agent = partner_id
|
|
id := testrand.UUID()
|
|
_, err := db.Console().Users().Insert(ctx, &console.User{
|
|
ID: id,
|
|
Email: "test@storj.test",
|
|
FullName: "Test Test",
|
|
PasswordHash: []byte{0, 1, 2, 3},
|
|
PartnerID: id,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
n++
|
|
// insert with user_agent = partner_id
|
|
id = testrand.UUID()
|
|
_, err = db.Console().Users().Insert(ctx, &console.User{
|
|
ID: id,
|
|
Email: "test@storj.test",
|
|
FullName: "Test Test",
|
|
PasswordHash: []byte{0, 1, 2, 3},
|
|
PartnerID: id,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
n++
|
|
// insert an entry with something not matching
|
|
_, err = db.Console().Users().Insert(ctx, &console.User{
|
|
ID: testrand.UUID(),
|
|
Email: "test@storj.test",
|
|
FullName: "Test Test",
|
|
PasswordHash: []byte{0, 1, 2, 3},
|
|
UserAgent: []byte("teststorj"),
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
_, users, err := db.Console().Users().GetByEmailWithUnverified(ctx, "test@storj.test")
|
|
require.NoError(t, err)
|
|
|
|
var updated int
|
|
for _, u := range users {
|
|
if u.UserAgent == nil {
|
|
updated++
|
|
}
|
|
}
|
|
require.Equal(t, n, updated)
|
|
n = 0
|
|
}
|
|
|
|
test(t, prepare, migrator.MigrateUsers, check, &migrator.Config{
|
|
Limit: 1,
|
|
})
|
|
}
|
|
|
|
// Test limited number of user_agent fields are updated correctly.
|
|
func TestMigrateUsersLimited(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
// insert an entry with valid user agent
|
|
_, err := db.Console().Users().Insert(ctx, &console.User{
|
|
ID: testrand.UUID(),
|
|
Email: "test@storj.test",
|
|
FullName: "Test Test",
|
|
PasswordHash: []byte{0, 1, 2, 3},
|
|
UserAgent: []byte("teststorj"),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// insert matching user_agent and partner id
|
|
id := testrand.UUID()
|
|
_, err = db.Console().Users().Insert(ctx, &console.User{
|
|
ID: testrand.UUID(),
|
|
Email: "test@storj.test",
|
|
FullName: "Test Test",
|
|
PasswordHash: []byte{0, 1, 2, 3},
|
|
PartnerID: id,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// insert '\x00000000000000000000000000000000' user_agent
|
|
id = testrand.UUID()
|
|
_, err = db.Console().Projects().Insert(ctx, &console.Project{
|
|
Name: "test",
|
|
Description: "test",
|
|
PartnerID: id,
|
|
OwnerID: testrand.UUID(),
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
maxUpdates := 1
|
|
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
_, users, err := db.Console().Users().GetByEmailWithUnverified(ctx, "test@storj.test")
|
|
require.NoError(t, err)
|
|
|
|
var updated int
|
|
for _, u := range users {
|
|
if u.UserAgent == nil {
|
|
updated++
|
|
}
|
|
}
|
|
require.Equal(t, maxUpdates, updated)
|
|
}
|
|
test(t, prepare, migrator.MigrateUsersLimited, check, &migrator.Config{
|
|
MaxUpdates: maxUpdates,
|
|
})
|
|
}
|
|
|
|
// Test no entries in table doesn't error.
|
|
func TestMigrateProjectsSelectNoRows(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {}
|
|
test(t, prepare, migrator.MigrateProjects, check, &migrator.Config{
|
|
Limit: 8,
|
|
})
|
|
}
|
|
|
|
// Test no entries in table doesn't error.
|
|
func TestMigrateProjectsLimitedSelectNoRows(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {}
|
|
test(t, prepare, migrator.MigrateProjectsLimited, check, &migrator.Config{
|
|
MaxUpdates: 1,
|
|
})
|
|
}
|
|
|
|
// Test no rows to update returns no error.
|
|
func TestMigrateProjectsUpdateNoRows(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
var id uuid.UUID
|
|
userAgent := []byte("teststorj")
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
|
|
proj, err := db.Console().Projects().Insert(ctx, &console.Project{
|
|
Name: "test",
|
|
Description: "test",
|
|
OwnerID: testrand.UUID(),
|
|
UserAgent: userAgent,
|
|
})
|
|
require.NoError(t, err)
|
|
id = proj.ID
|
|
}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
proj, err := db.Console().Projects().Get(ctx, id)
|
|
require.NoError(t, err)
|
|
require.Equal(t, userAgent, proj.UserAgent)
|
|
}
|
|
test(t, prepare, migrator.MigrateProjects, check, &migrator.Config{
|
|
Limit: 8,
|
|
})
|
|
}
|
|
|
|
// Test select offset beyond final row.
|
|
// With only one row, selecting with an offset of 1 will return 0 rows.
|
|
// Test that this is accounted for and updates the row correctly.
|
|
func TestMigrateProjectsSelectOffsetBeyondRowCount(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
var projID uuid.UUID
|
|
id := testrand.UUID()
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
prj, err := db.Console().Projects().Insert(ctx, &console.Project{
|
|
Name: "test",
|
|
Description: "test",
|
|
PartnerID: id,
|
|
OwnerID: testrand.UUID(),
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
projID = prj.ID
|
|
}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
proj, err := db.Console().Projects().Get(ctx, projID)
|
|
require.NoError(t, err)
|
|
require.Nil(t, proj.UserAgent)
|
|
}
|
|
test(t, prepare, migrator.MigrateProjects, check, &migrator.Config{
|
|
Limit: 8,
|
|
})
|
|
}
|
|
|
|
// Test user_agent field is updated correctly.
|
|
func TestMigrateProjects(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
var n int
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
// insert matching user_agent partner_id
|
|
id := testrand.UUID()
|
|
_, err := db.Console().Projects().Insert(ctx, &console.Project{
|
|
Name: "test",
|
|
Description: "test",
|
|
OwnerID: testrand.UUID(),
|
|
PartnerID: id,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
n++
|
|
// insert matching user_agent
|
|
id = testrand.UUID()
|
|
_, err = db.Console().Projects().Insert(ctx, &console.Project{
|
|
Name: "test1",
|
|
Description: "test1",
|
|
OwnerID: testrand.UUID(),
|
|
PartnerID: id,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
n++
|
|
// insert an entry with something not zero
|
|
_, err = db.Console().Projects().Insert(ctx, &console.Project{
|
|
Name: "test",
|
|
Description: "test",
|
|
PartnerID: testrand.UUID(),
|
|
OwnerID: testrand.UUID(),
|
|
UserAgent: []byte("teststorj"),
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
projects, err := db.Console().Projects().GetAll(ctx)
|
|
require.NoError(t, err)
|
|
|
|
var updated int
|
|
for _, prj := range projects {
|
|
if prj.UserAgent == nil {
|
|
updated++
|
|
}
|
|
}
|
|
require.Equal(t, n, updated)
|
|
n = 0
|
|
}
|
|
|
|
test(t, prepare, migrator.MigrateProjects, check, &migrator.Config{
|
|
Limit: 1,
|
|
})
|
|
}
|
|
|
|
// Test user_agent field is updated correctly.
|
|
func TestMigrateProjectsLimited(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
// insert an entry with valid user agent
|
|
_, err := db.Console().Projects().Insert(ctx, &console.Project{
|
|
Name: "test",
|
|
Description: "test",
|
|
OwnerID: testrand.UUID(),
|
|
UserAgent: []byte("teststorj"),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// insert matching user_agent
|
|
id := testrand.UUID()
|
|
_, err = db.Console().Projects().Insert(ctx, &console.Project{
|
|
Name: "test",
|
|
Description: "test",
|
|
OwnerID: testrand.UUID(),
|
|
UserAgent: id.Bytes(),
|
|
PartnerID: id,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// insert matching user_agent and partner id
|
|
id = testrand.UUID()
|
|
_, err = db.Console().Projects().Insert(ctx, &console.Project{
|
|
Name: "test",
|
|
Description: "test",
|
|
OwnerID: testrand.UUID(),
|
|
UserAgent: id.Bytes(),
|
|
PartnerID: id,
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
maxUpdates := 1
|
|
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
projects, err := db.Console().Projects().GetAll(ctx)
|
|
require.NoError(t, err)
|
|
|
|
var updated int
|
|
for _, prj := range projects {
|
|
if prj.UserAgent == nil {
|
|
updated++
|
|
}
|
|
}
|
|
require.Equal(t, maxUpdates, updated)
|
|
}
|
|
test(t, prepare, migrator.MigrateProjectsLimited, check, &migrator.Config{
|
|
MaxUpdates: maxUpdates,
|
|
})
|
|
}
|
|
|
|
// Test no entries in table doesn't error.
|
|
func TestMigrateAPIKeysSelectNoRows(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {}
|
|
test(t, prepare, migrator.MigrateAPIKeys, check, &migrator.Config{
|
|
Limit: 8,
|
|
})
|
|
}
|
|
|
|
// Test no entries in table doesn't error.
|
|
func TestMigrateAPIKeysLimitedSelectNoRows(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {}
|
|
test(t, prepare, migrator.MigrateAPIKeysLimited, check, &migrator.Config{
|
|
MaxUpdates: 1,
|
|
})
|
|
}
|
|
|
|
// Test no rows to update returns no error.
|
|
func TestMigrateAPIKeysUpdateNoRows(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
var testID uuid.UUID
|
|
id := testrand.UUID()
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
proj, err := db.Console().Projects().Insert(ctx, &console.Project{
|
|
Name: "test",
|
|
Description: "test",
|
|
OwnerID: testrand.UUID(),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
apikey, err := db.Console().APIKeys().Create(ctx, testrand.UUID().Bytes(), console.APIKeyInfo{
|
|
ProjectID: proj.ID,
|
|
Name: "test0",
|
|
Secret: []byte("test"),
|
|
PartnerID: id,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
testID = apikey.ID
|
|
}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
apikey, err := db.Console().APIKeys().Get(ctx, testID)
|
|
require.NoError(t, err)
|
|
require.Nil(t, apikey.UserAgent)
|
|
}
|
|
test(t, prepare, migrator.MigrateAPIKeys, check, &migrator.Config{
|
|
Limit: 8,
|
|
})
|
|
}
|
|
|
|
// Test select offset beyond final row.
|
|
// With only one row, selecting with an offset of 1 will return 0 rows.
|
|
// Test that this is accounted for and updates the row correctly.
|
|
func TestMigrateAPIKeysSelectOffsetBeyondRowCount(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
var testID uuid.UUID
|
|
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
prj, err := db.Console().Projects().Insert(ctx, &console.Project{
|
|
Name: "test",
|
|
Description: "test",
|
|
PartnerID: testrand.UUID(),
|
|
OwnerID: testrand.UUID(),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
id := testrand.UUID()
|
|
apiKey, err := db.Console().APIKeys().Create(ctx, testrand.UUID().Bytes(), console.APIKeyInfo{
|
|
ProjectID: prj.ID,
|
|
PartnerID: id,
|
|
Name: "test0",
|
|
Secret: []byte("test"),
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
testID = apiKey.ID
|
|
}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
apiKey, err := db.Console().APIKeys().Get(ctx, testID)
|
|
require.NoError(t, err)
|
|
require.Nil(t, apiKey.UserAgent)
|
|
}
|
|
test(t, prepare, migrator.MigrateAPIKeys, check, &migrator.Config{
|
|
Limit: 8,
|
|
})
|
|
}
|
|
|
|
// Test user_agent field is updated correctly.
|
|
func TestMigrateAPIKeys(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
var n int
|
|
var projID uuid.UUID
|
|
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
proj, err := db.Console().Projects().Insert(ctx, &console.Project{
|
|
Name: "test",
|
|
Description: "test",
|
|
OwnerID: testrand.UUID(),
|
|
})
|
|
require.NoError(t, err)
|
|
projID = proj.ID
|
|
|
|
// insert matching user_agent and partner id
|
|
id := testrand.UUID()
|
|
_, err = db.Console().APIKeys().Create(ctx, testrand.UUID().Bytes(), console.APIKeyInfo{
|
|
ProjectID: projID,
|
|
Name: "test0",
|
|
Secret: []byte("test"),
|
|
PartnerID: id,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
n++
|
|
|
|
// insert another matching user_agent and partner id
|
|
id = testrand.UUID()
|
|
_, err = db.Console().APIKeys().Create(ctx, testrand.UUID().Bytes(), console.APIKeyInfo{
|
|
ProjectID: projID,
|
|
Name: "test1",
|
|
Secret: []byte("test1"),
|
|
PartnerID: id,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
n++
|
|
|
|
// insert an entry with something not zero
|
|
_, err = db.Console().APIKeys().Create(ctx, testrand.UUID().Bytes(), console.APIKeyInfo{
|
|
ProjectID: projID,
|
|
PartnerID: testrand.UUID(),
|
|
Name: "test2",
|
|
Secret: []byte("test"),
|
|
UserAgent: []byte("teststorj"),
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
keyPage, err := db.Console().APIKeys().GetPagedByProjectID(ctx, projID, console.APIKeyCursor{Page: 1, Limit: 1000})
|
|
require.NoError(t, err)
|
|
|
|
var updated int
|
|
for _, key := range keyPage.APIKeys {
|
|
if key.UserAgent == nil {
|
|
updated++
|
|
}
|
|
}
|
|
require.Equal(t, n, updated)
|
|
n = 0
|
|
}
|
|
|
|
test(t, prepare, migrator.MigrateAPIKeys, check, &migrator.Config{
|
|
Limit: 8,
|
|
})
|
|
}
|
|
|
|
// Test user_agent field is updated correctly.
|
|
func TestMigrateAPIKeysLimited(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
var projID uuid.UUID
|
|
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
proj, err := db.Console().Projects().Insert(ctx, &console.Project{
|
|
Name: "test",
|
|
Description: "test",
|
|
OwnerID: testrand.UUID(),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
projID = proj.ID
|
|
|
|
// insert an entry with valid user agent
|
|
_, err = db.Console().APIKeys().Create(ctx, testrand.UUID().Bytes(), console.APIKeyInfo{
|
|
ProjectID: projID,
|
|
Name: "test0",
|
|
Secret: []byte("test"),
|
|
UserAgent: []byte("teststorj"),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// insert matching user_agent and partner id
|
|
id := testrand.UUID()
|
|
_, err = db.Console().APIKeys().Create(ctx, testrand.UUID().Bytes(), console.APIKeyInfo{
|
|
ProjectID: projID,
|
|
Name: "test1",
|
|
Secret: []byte("test"),
|
|
PartnerID: id,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// insert another matching user_agent and partner id
|
|
id = testrand.UUID()
|
|
_, err = db.Console().APIKeys().Create(ctx, testrand.UUID().Bytes(), console.APIKeyInfo{
|
|
ProjectID: projID,
|
|
PartnerID: id,
|
|
Name: "test2",
|
|
Secret: []byte("test"),
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
maxUpdates := 1
|
|
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
keyPage, err := db.Console().APIKeys().GetPagedByProjectID(ctx, projID, console.APIKeyCursor{Page: 1, Limit: 1000})
|
|
require.NoError(t, err)
|
|
|
|
var updated int
|
|
for _, key := range keyPage.APIKeys {
|
|
if key.UserAgent == nil {
|
|
updated++
|
|
}
|
|
}
|
|
require.Equal(t, maxUpdates, updated)
|
|
|
|
}
|
|
test(t, prepare, migrator.MigrateAPIKeysLimited, check, &migrator.Config{
|
|
MaxUpdates: maxUpdates,
|
|
})
|
|
}
|
|
|
|
// Test no entries in table doesn't error.
|
|
func TestMigrateBucketMetainfosSelectNoRows(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {}
|
|
test(t, prepare, migrator.MigrateBucketMetainfos, check, &migrator.Config{
|
|
Limit: 8,
|
|
})
|
|
}
|
|
|
|
// Test no entries in table doesn't error.
|
|
func TestMigrateBucketMetainfosLimitedSelectNoRows(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {}
|
|
test(t, prepare, migrator.MigrateBucketMetainfosLimited, check, &migrator.Config{
|
|
MaxUpdates: 1,
|
|
})
|
|
}
|
|
|
|
// Test no rows to update returns no error.
|
|
func TestMigrateBucketMetainfosUpdateNoRows(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
bName := "test1"
|
|
var projID uuid.UUID
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
proj, err := db.Console().Projects().Insert(ctx, &console.Project{
|
|
Name: "test",
|
|
Description: "test",
|
|
OwnerID: testrand.UUID(),
|
|
})
|
|
require.NoError(t, err)
|
|
projID = proj.ID
|
|
|
|
_, err = db.Buckets().CreateBucket(ctx, storj.Bucket{
|
|
ID: testrand.UUID(),
|
|
Name: "test1",
|
|
ProjectID: projID,
|
|
UserAgent: []byte("teststorj"),
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
b, err := db.Buckets().GetBucket(ctx, []byte(bName), projID)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, b.UserAgent)
|
|
}
|
|
test(t, prepare, migrator.MigrateBucketMetainfos, check, &migrator.Config{
|
|
Limit: 8,
|
|
})
|
|
}
|
|
|
|
// Test select offset beyond final row.
|
|
// With only one row, selecting with an offset of 1 will return 0 rows.
|
|
// Test that this is accounted for and updates the row correctly.
|
|
func TestMigrateBucketMetainfosSelectOffsetBeyondRowCount(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
var projID uuid.UUID
|
|
bucket := []byte("test")
|
|
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
prj, err := db.Console().Projects().Insert(ctx, &console.Project{
|
|
Name: "test",
|
|
Description: "test",
|
|
OwnerID: testrand.UUID(),
|
|
})
|
|
require.NoError(t, err)
|
|
projID = prj.ID
|
|
|
|
id := testrand.UUID()
|
|
_, err = db.Buckets().CreateBucket(ctx, storj.Bucket{
|
|
ID: testrand.UUID(),
|
|
Name: string(bucket),
|
|
ProjectID: projID,
|
|
PartnerID: id,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
b, err := db.Buckets().GetBucket(ctx, bucket, projID)
|
|
require.NoError(t, err)
|
|
require.Nil(t, b.UserAgent)
|
|
}
|
|
test(t, prepare, migrator.MigrateBucketMetainfos, check, &migrator.Config{
|
|
Limit: 8,
|
|
})
|
|
}
|
|
|
|
// Test user_agent field is updated correctly.
|
|
func TestMigrateBucketMetainfos(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
var n int
|
|
var projID uuid.UUID
|
|
zeroedUUID := uuid.UUID{}.Bytes()
|
|
require.NotNil(t, zeroedUUID)
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
proj, err := db.Console().Projects().Insert(ctx, &console.Project{
|
|
Name: "test",
|
|
Description: "test",
|
|
OwnerID: testrand.UUID(),
|
|
})
|
|
require.NoError(t, err)
|
|
projID = proj.ID
|
|
|
|
// insert matching user_agent and partner id
|
|
id := testrand.UUID()
|
|
_, err = db.Buckets().CreateBucket(ctx, storj.Bucket{
|
|
ID: id,
|
|
Name: "test0",
|
|
ProjectID: projID,
|
|
PartnerID: id,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
n++
|
|
|
|
// insert another matching user_agent and partner id
|
|
id = testrand.UUID()
|
|
_, err = db.Buckets().CreateBucket(ctx, storj.Bucket{
|
|
ID: id,
|
|
Name: "test1",
|
|
ProjectID: projID,
|
|
PartnerID: id,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
n++
|
|
|
|
// insert an entry with something not zero
|
|
_, err = db.Buckets().CreateBucket(ctx, storj.Bucket{
|
|
ID: testrand.UUID(),
|
|
Name: "test2",
|
|
ProjectID: projID,
|
|
PartnerID: testrand.UUID(),
|
|
UserAgent: []byte("teststorj"),
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
list, err := db.Buckets().ListBuckets(ctx, projID, storj.BucketListOptions{Direction: storj.Forward}, macaroon.AllowedBuckets{All: true})
|
|
require.NoError(t, err)
|
|
|
|
var updated int
|
|
for _, b := range list.Items {
|
|
if b.UserAgent == nil {
|
|
updated++
|
|
}
|
|
}
|
|
require.Equal(t, n, updated)
|
|
n = 0
|
|
}
|
|
|
|
test(t, prepare, migrator.MigrateBucketMetainfos, check, &migrator.Config{
|
|
Limit: 8,
|
|
})
|
|
}
|
|
|
|
// Test user_agent field is updated correctly.
|
|
func TestMigrateBucketMetainfosLimited(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
testID := testrand.UUID()
|
|
zeroedUUID := uuid.UUID{}.Bytes()
|
|
require.NotNil(t, zeroedUUID)
|
|
var projID uuid.UUID
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
proj, err := db.Console().Projects().Insert(ctx, &console.Project{
|
|
Name: "test",
|
|
Description: "test",
|
|
OwnerID: testrand.UUID(),
|
|
UserAgent: []byte("teststorj"),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
projID = proj.ID
|
|
|
|
// insert matching user_agent
|
|
id := testrand.UUID()
|
|
_, err = db.Buckets().CreateBucket(ctx, storj.Bucket{
|
|
ID: testID,
|
|
Name: "test0",
|
|
ProjectID: projID,
|
|
PartnerID: id,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// insert another matching user_agent and partner id
|
|
id = testrand.UUID()
|
|
_, err = db.Buckets().CreateBucket(ctx, storj.Bucket{
|
|
ID: testrand.UUID(),
|
|
Name: "test1",
|
|
ProjectID: projID,
|
|
PartnerID: id,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
maxUpdates := 1
|
|
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
list, err := db.Buckets().ListBuckets(ctx, projID, storj.BucketListOptions{Direction: storj.Forward}, macaroon.AllowedBuckets{All: true})
|
|
require.NoError(t, err)
|
|
|
|
var updated int
|
|
for _, b := range list.Items {
|
|
if b.UserAgent == nil {
|
|
updated++
|
|
}
|
|
}
|
|
require.Equal(t, maxUpdates, updated)
|
|
}
|
|
test(t, prepare, migrator.MigrateBucketMetainfosLimited, check, &migrator.Config{
|
|
MaxUpdates: maxUpdates,
|
|
})
|
|
}
|
|
|
|
// Test no entries in table doesn't error.
|
|
func TestMigrateValueAttributionsSelectNoRows(t *testing.T) {
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {}
|
|
test(t, prepare, migrator.MigrateValueAttributions, check, &migrator.Config{
|
|
Limit: 8,
|
|
})
|
|
}
|
|
|
|
// Test no entries in table doesn't error.
|
|
func TestMigrateValueAttributionsLimitedSelectNoRows(t *testing.T) {
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {}
|
|
test(t, prepare, migrator.MigrateValueAttributionsLimited, check, &migrator.Config{
|
|
MaxUpdates: 1,
|
|
})
|
|
}
|
|
|
|
// Test no rows to update returns no error.
|
|
func TestMigrateValueAttributionsUpdateNoRows(t *testing.T) {
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
partnerID := testrand.UUID()
|
|
ua := []byte("test")
|
|
projID := testrand.UUID()
|
|
bName := []byte("test")
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
|
|
_, err := db.Attribution().Insert(ctx, &attribution.Info{
|
|
ProjectID: projID,
|
|
PartnerID: partnerID,
|
|
BucketName: bName,
|
|
UserAgent: ua,
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
att, err := db.Attribution().Get(ctx, projID, bName)
|
|
require.NoError(t, err)
|
|
require.Equal(t, partnerID, att.PartnerID)
|
|
require.Equal(t, ua, att.UserAgent)
|
|
}
|
|
test(t, prepare, migrator.MigrateValueAttributions, check, &migrator.Config{
|
|
Limit: 8,
|
|
})
|
|
}
|
|
|
|
// Test select offset beyond final row.
|
|
// With only one row, selecting with an offset of 1 will return 0 rows.
|
|
// Test that this is accounted for and updates the row correctly.
|
|
func TestMigrateValueAttributionsSelectOffsetBeyondRowCount(t *testing.T) {
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
projID := testrand.UUID()
|
|
bucket := []byte("test")
|
|
id := testrand.UUID()
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
_, err := db.Attribution().Insert(ctx, &attribution.Info{
|
|
ProjectID: projID,
|
|
PartnerID: id,
|
|
BucketName: bucket,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
att, err := db.Attribution().Get(ctx, projID, bucket)
|
|
require.NoError(t, err)
|
|
require.Nil(t, att.UserAgent)
|
|
}
|
|
test(t, prepare, migrator.MigrateValueAttributions, check, &migrator.Config{
|
|
Limit: 8,
|
|
})
|
|
}
|
|
|
|
// Test user_agent field is updated correctly.
|
|
func TestMigrateValueAttributions(t *testing.T) {
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
type info struct {
|
|
bucket []byte
|
|
project uuid.UUID
|
|
}
|
|
|
|
var n int
|
|
zeroedUUID := uuid.UUID{}.Bytes()
|
|
require.NotNil(t, zeroedUUID)
|
|
var infos []info
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
|
|
// insert matching user_agent partner id
|
|
id := testrand.UUID()
|
|
b := []byte("test0")
|
|
infos = append(infos, info{b, id})
|
|
_, err := db.Attribution().Insert(ctx, &attribution.Info{
|
|
ProjectID: id,
|
|
PartnerID: id,
|
|
BucketName: b,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
n++
|
|
|
|
// insert another matching user_agent partner id
|
|
id = testrand.UUID()
|
|
infos = append(infos, info{b, id})
|
|
_, err = db.Attribution().Insert(ctx, &attribution.Info{
|
|
ProjectID: id,
|
|
PartnerID: id,
|
|
BucketName: b,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
n++
|
|
|
|
// insert without zeroes
|
|
id = testrand.UUID()
|
|
_, err = db.Attribution().Insert(ctx, &attribution.Info{
|
|
ProjectID: id,
|
|
PartnerID: id,
|
|
BucketName: b,
|
|
UserAgent: []byte("teststorj"),
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
var updated int
|
|
for _, in := range infos {
|
|
att, err := db.Attribution().Get(ctx, in.project, in.bucket)
|
|
require.NoError(t, err)
|
|
if att.UserAgent == nil {
|
|
updated++
|
|
}
|
|
}
|
|
require.Equal(t, n, updated)
|
|
n = 0
|
|
// clear infos for the subsequent CRDB test
|
|
infos = []info{}
|
|
}
|
|
|
|
test(t, prepare, migrator.MigrateValueAttributions, check, &migrator.Config{
|
|
Limit: 1,
|
|
})
|
|
}
|
|
|
|
// Test user_agent field is updated correctly.
|
|
func TestMigrateValueAttributionsLimited(t *testing.T) {
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
type info struct {
|
|
bucket []byte
|
|
project uuid.UUID
|
|
}
|
|
|
|
zeroedUUID := uuid.UUID{}.Bytes()
|
|
require.NotNil(t, zeroedUUID)
|
|
var infos []info
|
|
prepare := func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB) {
|
|
// insert with matching user agent and partner id
|
|
id := testrand.UUID()
|
|
b := []byte("test0")
|
|
infos = append(infos, info{b, id})
|
|
_, err := db.Attribution().Insert(ctx, &attribution.Info{
|
|
ProjectID: id,
|
|
PartnerID: id,
|
|
BucketName: b,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// insert another with zeroes
|
|
id = testrand.UUID()
|
|
infos = append(infos, info{b, id})
|
|
_, err = db.Attribution().Insert(ctx, &attribution.Info{
|
|
ProjectID: id,
|
|
PartnerID: id,
|
|
BucketName: b,
|
|
UserAgent: id.Bytes(),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// insert without zeroes
|
|
id = testrand.UUID()
|
|
infos = append(infos, info{b, id})
|
|
_, err = db.Attribution().Insert(ctx, &attribution.Info{
|
|
ProjectID: id,
|
|
PartnerID: id,
|
|
BucketName: b,
|
|
UserAgent: []byte("teststorj"),
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
maxUpdates := 1
|
|
|
|
check := func(t *testing.T, ctx context.Context, db satellite.DB) {
|
|
var updated int
|
|
for _, in := range infos {
|
|
att, err := db.Attribution().Get(ctx, in.project, in.bucket)
|
|
require.NoError(t, err)
|
|
if att.UserAgent == nil {
|
|
updated++
|
|
}
|
|
}
|
|
require.Equal(t, maxUpdates, updated)
|
|
|
|
// clear infos for the subsequent CRDB test
|
|
infos = []info{}
|
|
}
|
|
test(t, prepare, migrator.MigrateValueAttributionsLimited, check, &migrator.Config{
|
|
MaxUpdates: maxUpdates,
|
|
})
|
|
}
|
|
|
|
func test(t *testing.T, prepare func(t *testing.T, ctx *testcontext.Context, rawDB *dbutil.TempDatabase, db satellite.DB),
|
|
migrate func(ctx context.Context, log *zap.Logger, conn *pgx.Conn, config migrator.Config) (err error),
|
|
check func(t *testing.T, ctx context.Context, db satellite.DB), config *migrator.Config) {
|
|
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
log := zaptest.NewLogger(t)
|
|
|
|
for _, satelliteDB := range satellitedbtest.Databases() {
|
|
satelliteDB := satelliteDB
|
|
t.Run(satelliteDB.Name, func(t *testing.T) {
|
|
schemaSuffix := satellitedbtest.SchemaSuffix()
|
|
schema := satellitedbtest.SchemaName(t.Name(), "category", 0, schemaSuffix)
|
|
|
|
tempDB, err := tempdb.OpenUnique(ctx, satelliteDB.MasterDB.URL, schema)
|
|
require.NoError(t, err)
|
|
|
|
db, err := satellitedbtest.CreateMasterDBOnTopOf(ctx, log, tempDB)
|
|
require.NoError(t, err)
|
|
defer ctx.Check(db.Close)
|
|
|
|
err = db.TestingMigrateToLatest(ctx)
|
|
require.NoError(t, err)
|
|
|
|
prepare(t, ctx, tempDB, db)
|
|
|
|
mConnStr := strings.Replace(tempDB.ConnStr, "cockroach", "postgres", 1)
|
|
|
|
conn, err := pgx.Connect(ctx, mConnStr)
|
|
require.NoError(t, err)
|
|
|
|
err = migrate(ctx, log, conn, *config)
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, err)
|
|
|
|
check(t, ctx, db)
|
|
})
|
|
}
|
|
}
|