Code at the kopia wrapper layer that allows configuring kopia for retention if desired. Includes some tests that require running against a bucket with object locking enabled --- #### Does this PR need a docs update or release note? - [ ] ✅ Yes, it's included - [ ] 🕐 Yes, but in a later PR - [x] ⛔ No #### Type of change - [x] 🌻 Feature - [ ] 🐛 Bugfix - [ ] 🗺️ Documentation - [ ] 🤖 Supportability/Tests - [ ] 💻 CI/Deployment - [ ] 🧹 Tech Debt/Cleanup #### Issue(s) * #3519 #### Test Plan - [x] 💪 Manual - [x] ⚡ Unit test - [ ] 💚 E2E
235 lines
4.9 KiB
Go
235 lines
4.9 KiB
Go
package tester
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/alcionai/clues"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/stretchr/testify/suite"
|
|
"golang.org/x/exp/maps"
|
|
)
|
|
|
|
// Flags for declaring which scope of tests to run.
|
|
const (
|
|
CorsoCITests = "CORSO_CI_TESTS"
|
|
CorsoE2ETests = "CORSO_E2E_TESTS"
|
|
CorsoLoadTests = "CORSO_LOAD_TESTS"
|
|
CorsoNightlyTests = "CORSO_NIGHTLY_TESTS"
|
|
CorsoRetentionTests = "CORSO_RETENTION_TESTS"
|
|
)
|
|
|
|
type Suite interface {
|
|
suite.TestingSuite
|
|
Run(name string, subtest func()) bool
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Unit
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func NewUnitSuite(t *testing.T) *unitSuite {
|
|
return new(unitSuite)
|
|
}
|
|
|
|
type unitSuite struct {
|
|
suite.Suite
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Integration
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func NewIntegrationSuite(
|
|
t *testing.T,
|
|
envSets [][]string,
|
|
runOnAnyEnv ...string,
|
|
) *integrationSuite {
|
|
// ensure clues does not obscure logging
|
|
clues.SetHasher(clues.NoHash())
|
|
|
|
RunOnAny(
|
|
t,
|
|
append(
|
|
[]string{CorsoCITests},
|
|
runOnAnyEnv...,
|
|
)...,
|
|
)
|
|
|
|
MustGetEnvSets(t, envSets...)
|
|
|
|
return new(integrationSuite)
|
|
}
|
|
|
|
type integrationSuite struct {
|
|
suite.Suite
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Smoke/e2e
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func NewE2ESuite(
|
|
t *testing.T,
|
|
envSets [][]string,
|
|
runOnAnyEnv ...string,
|
|
) *e2eSuite {
|
|
// ensure clues does not obscure logging
|
|
clues.SetHasher(clues.NoHash())
|
|
|
|
RunOnAny(
|
|
t,
|
|
append(
|
|
[]string{CorsoE2ETests},
|
|
runOnAnyEnv...,
|
|
)...,
|
|
)
|
|
|
|
MustGetEnvSets(t, envSets...)
|
|
|
|
return new(e2eSuite)
|
|
}
|
|
|
|
type e2eSuite struct {
|
|
suite.Suite
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Load
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func NewLoadSuite(
|
|
t *testing.T,
|
|
envSets [][]string,
|
|
runOnAnyEnv ...string,
|
|
) *loadSuite {
|
|
// ensure clues does not obscure logging
|
|
clues.SetHasher(clues.NoHash())
|
|
|
|
RunOnAny(
|
|
t,
|
|
append(
|
|
[]string{CorsoLoadTests},
|
|
runOnAnyEnv...,
|
|
)...,
|
|
)
|
|
|
|
MustGetEnvSets(t, envSets...)
|
|
|
|
return new(loadSuite)
|
|
}
|
|
|
|
type loadSuite struct {
|
|
suite.Suite
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Nightly
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func NewNightlySuite(
|
|
t *testing.T,
|
|
envSets [][]string,
|
|
runOnAnyEnv ...string,
|
|
) *nightlySuite {
|
|
// ensure clues does not obscure logging
|
|
clues.SetHasher(clues.NoHash())
|
|
|
|
RunOnAny(
|
|
t,
|
|
append(
|
|
[]string{CorsoNightlyTests},
|
|
runOnAnyEnv...,
|
|
)...,
|
|
)
|
|
|
|
MustGetEnvSets(t, envSets...)
|
|
|
|
return new(nightlySuite)
|
|
}
|
|
|
|
type nightlySuite struct {
|
|
suite.Suite
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Retention; requires object locking enabled on the S3 bucket.
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func NewRetentionSuite(
|
|
t *testing.T,
|
|
envSets [][]string,
|
|
runOnAnyEnv ...string,
|
|
) *retentionSuite {
|
|
// ensure clues does not obscure logging
|
|
clues.SetHasher(clues.NoHash())
|
|
|
|
RunOnAny(
|
|
t,
|
|
append(
|
|
[]string{CorsoRetentionTests},
|
|
runOnAnyEnv...,
|
|
)...,
|
|
)
|
|
|
|
MustGetEnvSets(t, envSets...)
|
|
|
|
return new(retentionSuite)
|
|
}
|
|
|
|
type retentionSuite struct {
|
|
suite.Suite
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Run Condition Checkers
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// RunOnAny takes in a list of env variable names and returns
|
|
// an error if all of them are zero valued. Implication being:
|
|
// if any of those env vars are truthy, you should run the
|
|
// subsequent tests.
|
|
func RunOnAny(t *testing.T, tests ...string) {
|
|
var l int
|
|
for _, test := range tests {
|
|
l += len(os.Getenv(test))
|
|
}
|
|
|
|
if l == 0 {
|
|
t.Skipf(
|
|
"one or more env vars must be flagged to run this test: %v",
|
|
strings.Join(tests, ", "))
|
|
}
|
|
}
|
|
|
|
// MustGetEnvVars retrieves the provided env vars from the os.
|
|
// Retrieved values are populated into the resulting map.
|
|
// If any of the env values are zero length, the test errors.
|
|
func MustGetEnvVars(t *testing.T, evs ...string) map[string]string {
|
|
vals := map[string]string{}
|
|
|
|
for _, ev := range evs {
|
|
ge := os.Getenv(ev)
|
|
require.NotEmpty(t, ev, ev+" env var required for test suite")
|
|
|
|
vals[ev] = ge
|
|
}
|
|
|
|
return vals
|
|
}
|
|
|
|
// MustGetEnvSls retrieves the provided env vars from the os.
|
|
// Retrieved values are populated into the resulting map.
|
|
// If any of the env values are zero length, the test errors.
|
|
func MustGetEnvSets(t *testing.T, evs ...[]string) map[string]string {
|
|
vals := map[string]string{}
|
|
|
|
for _, ev := range evs {
|
|
r := MustGetEnvVars(t, ev...)
|
|
maps.Copy(vals, r)
|
|
}
|
|
|
|
return vals
|
|
}
|