package server_test import ( "context" "database/sql" "fmt" "os" "testing" "time" server "edge-infra.dev/pkg/edge/psqlinjector" "edge-infra.dev/test/f2" "edge-infra.dev/test/f2/x/postgres" "edge-infra.dev/test/f2/x/pstest" "cloud.google.com/go/pubsub" "github.com/google/uuid" "github.com/stretchr/testify/require" "google.golang.org/api/option" ) var f2f f2.Framework func TestMain(m *testing.M) { var pg = postgres.New(postgres.ApplySeedModel()) // don't set postgres.SkipSchemaIsolation() var pub = pstest.New(pstest.WithProjectID("test_id")) f2f = f2.New(context.Background(), f2.WithExtensions(pg, pub)) os.Exit(f2f.Run(m)) } func setupConfig(ctx f2.Context, t *testing.T, cfg *server.Config) f2.Context { cfg.DelayScrapeMessageProcessing = 10 * time.Millisecond cfg.HealthzAddr = "127.0.0.1:0" cfg.MetricsAddr = "127.0.0.1:0" cfg.ForemanProjectID = "ret-edge-foo0-foreman" cfg.TopicID = "kinform-psqlinjector" cfg.SubscriptionID = "psqlinjector" cfg.TestPubSubConn = pstest.FromContextT(ctx, t).Conn cfg.PollBannersMaxRetries = 1 cfg.PollBannersPeriod = 27 * time.Millisecond cfg.PollSubscriptionExistsPeriod = 11 * time.Millisecond cfg.DB = postgres.FromContextT(ctx, t).DB() return ctx } func createPubSubClient(ctx f2.Context, t *testing.T, projectID string) *pubsub.Client { ps := pstest.FromContextT(ctx, t) client, err := pubsub.NewClient(ctx, projectID, option.WithGRPCConn(ps.Conn)) require.NoError(t, err, "error creating pubsub client") return client } func createKinformTopics(ctx f2.Context, t *testing.T, cfg *server.Config, projectIDs ...string) f2.Context { for _, p := range projectIDs { var client = createPubSubClient(ctx, t, p) topic, err := client.CreateTopic(ctx, cfg.TopicID) require.NoError(t, err, "error creating pubsub topic") exists, err := topic.Exists(ctx) require.NoError(t, err, "error checking if topic exists") require.True(t, exists, "topic does not exist") sub, err := client.CreateSubscription(ctx, cfg.SubscriptionID, pubsub.SubscriptionConfig{Topic: topic}) require.NoError(t, err, "error creating subscription") exists, err = sub.Exists(ctx) require.NoError(t, err, "error checking if subscription exists") require.True(t, exists, "subscription does not exist") } return ctx } // populateTablesWithProjectIDs inserts each project ID into the database func populateTablesWithProjectIDs(ctx f2.Context, t *testing.T, projectIDs ...string) (clusterEdgeIDs map[string]uuid.UUID) { // minimum statments needed to create these entries. const stmtInsertTenant = "INSERT INTO tenants (tenant_edge_id, org_id, org_name) VALUES ($1, $2, $3)" const stmtInsertBanner = "INSERT INTO banners(project_id, banner_edge_id, banner_bsl_id, banner_name, tenant_edge_id) VALUES($1, $2, $3, $4, $5)" const stmtInsertCluster = "INSERT INTO clusters(cluster_edge_id, project_id, banner_edge_id, cluster_name) VALUES($1, $2, $3, $4)" var db = postgres.FromContextT(ctx, t).DB() var tenantEdgeID = uuid.New().String() var tenantOrgID = uuid.New().String() var tenantOrgName = fmt.Sprintf("tenant-%s", tenantOrgID) _, err := db.ExecContext(ctx, stmtInsertTenant, tenantEdgeID, tenantOrgID, tenantOrgName) require.NoError(t, err, "could not create tenant in database") var bannerIDs = make(map[string]string) for _, p := range projectIDs { var name = fmt.Sprintf("banner-%s", p) var bslID = fmt.Sprintf("bsl-id-%s", p) var id = uuid.New().String() bannerIDs[p] = id _, err = db.ExecContext(ctx, stmtInsertBanner, p, id, bslID, name, tenantEdgeID) require.NoError(t, err, "could not create banner in database") } clusterEdgeIDs = make(map[string]uuid.UUID) for i, p := range projectIDs { var name = fmt.Sprintf("cluster-%d", i) var id = uuid.New() clusterEdgeIDs[p] = id _, err := db.ExecContext(ctx, stmtInsertCluster, id.String(), p, bannerIDs[p], name) require.NoError(t, err, "could not create cluster in database") } // sanity check require.Equalf(t, len(clusterEdgeIDs), len(projectIDs), "there were duplicate projectIDs provided to this function: %v", projectIDs) return clusterEdgeIDs } func selectInfraStatusUpdatedAt(ctx f2.Context, t *testing.T, clusterEdgeIDs map[string]uuid.UUID) map[string]time.Time { var stmt = "SELECT infra_status_updated_at FROM clusters WHERE cluster_edge_id=$1" var db = postgres.FromContextT(ctx, t).DB() var m = make(map[string]time.Time) for p, ceid := range clusterEdgeIDs { var updated sql.NullTime // infra_status_updated_at can be null var row = db.QueryRowContext(ctx, stmt, ceid.String()) require.NoErrorf(t, row.Scan(&updated), "unable to query cluster infra_status_updated_at for projectID %q", p) m[p] = updated.Time // treat null as zero. } return m }