package lifttest import ( "fmt" "io/fs" "os" "os/exec" "path/filepath" "testing" "github.com/bazelbuild/rules_go/go/runfiles" "github.com/stretchr/testify/assert" "gopkg.in/yaml.v2" "edge-infra.dev/pkg/f8n/warehouse/lift" "edge-infra.dev/pkg/f8n/warehouse/oci/layout" "edge-infra.dev/pkg/k8s/kustomize" "edge-infra.dev/pkg/lib/build/bazel" "edge-infra.dev/pkg/lib/build/git" "edge-infra.dev/pkg/lib/cli/sh" "edge-infra.dev/test/fixtures" ) var ( dummyInfraCfg = lift.CapabilityConfig{ Package: "fake/infra-package", ResourceMatcher: lift.ResourceMatcher{ APIGroups: []string{"fake.apigroup.u"}, }, } cfg lift.Config path string ) type Option = func(*options) type options struct { fixtures bool } func makeOptions(opts ...Option) options { o := options{} for _, opt := range opts { opt(&o) } return o } // Setup sets the required environment variables for lift, given a testing struct and // a bazel.NewTestTmpDir() func Setup(t *testing.T, dir string, opts ...Option) { options := makeOptions(opts...) if options.fixtures { path = fixturesSetup(t, dir) } if !options.fixtures { cfg = lift.Config{Infrastructure: dummyInfraCfg} path = dir } gr := createTestGitRepo(t, path) assert.NoError(t, os.Chdir(gr)) g := git.NewInDir(gr) gPath, err := g.Path() if err != nil { t.Fatal(err) } WriteCfg(t, &cfg, gPath) if os.Getenv("WAREHOUSE_REPO") == "" { repo := "us-east1-docker.pkg.dev" t.Setenv("WAREHOUSE_REPO", repo) } t.Setenv("WAREHOUSE_PATH", path) cachepath := "test/cache" t.Setenv("WAREHOUSE_CACHE", cachepath) } // Writes a cfg and .version file to given path which are required for a lift build func WriteCfg(t *testing.T, cfg *lift.Config, path string) { cfgPath := filepath.Join(path, "warehouse.yaml") versionPath := filepath.Join(path, ".version") t.Helper() data, err := yaml.Marshal(cfg) assert.NoError(t, err) assert.NoError(t, os.WriteFile(cfgPath, data, 0644)) assert.NoError(t, os.WriteFile(versionPath, []byte("0.17.0"), 0644)) t.Setenv("WAREHOUSE_CONFIG", cfgPath) } // Binary for executable lift set up utilizing current set environment variables // (WAREHOUSE_PATH, WAREHOUSE_CONFIG, WAREHOUSE_CACHE) func CreateLiftBinary() (string, error) { var path string var err error if ws := os.Getenv(bazel.TestWorkspace); ws == "" { path, err = exec.LookPath("lift") if err != nil { return "", fmt.Errorf("unable to locate path at %v", path) } } else { path, err = runfiles.Rlocation(filepath.Join(ws, "cmd/f8n/warehouse/lift/lift_/lift")) if err != nil { return "", fmt.Errorf("unable to create absolute path at %v", path) } } return path, nil } func createTestGitRepo(t *testing.T, dir string) string { t.Helper() repo, err := os.MkdirTemp(dir, "git_test-*") assert.NoError(t, err) t.Log("test repo dir", repo) shell := sh.NewInDir(repo) for _, c := range []string{ "git init -q", "git config user.name \"testbot\"", "git config user.email \"testmail@testworld.co\"", "git checkout -b test", // remote ssh url added to test conversion to https "git remote add origin git@github.com:testworld", "git commit --allow-empty -m \"\"", } { assert.NoError(t, shell.RunE(c)) } return repo } func fixturesSetup(t *testing.T, dir string) string { f, err := fs.Sub(fixtures.PalletFixtures, "warehouse/src") if err != nil { t.Fatal(err) } testFS := &kustomize.FS{FS: f} p, err := layout.FromFS(testFS.FS, filepath.Join(dir, "warehouse/src")) if err != nil { t.Fatal() } path := string(p.Path) testCfgBytes, err := testFS.ReadFile(".warehouse.yaml") if err != nil { t.Fatalf("failed to read .warehouse.yaml in test fs: %s", err) } cfg = lift.Config{} err = yaml.Unmarshal(testCfgBytes, &cfg) if err != nil { t.Fatalf("failed to unmarshal test cfg: %s", err) } return path } // Creates a lift config from test fixtures file system func WithFixtures() Option { return func(o *options) { o.fixtures = true } }