From 24ada10342fff10d1d8c3b63365fa0436f09a939 Mon Sep 17 00:00:00 2001 From: Tolga Ceylan Date: Fri, 18 May 2018 16:58:45 -0700 Subject: [PATCH] fn: in api tests move singleton server into TestMain (#1010) --- test/fn-api-tests/init_test.go | 71 ++++++++++++++++++++++ test/fn-api-tests/utils.go | 107 --------------------------------- 2 files changed, 71 insertions(+), 107 deletions(-) diff --git a/test/fn-api-tests/init_test.go b/test/fn-api-tests/init_test.go index 229862504..8cf1a6f5c 100644 --- a/test/fn-api-tests/init_test.go +++ b/test/fn-api-tests/init_test.go @@ -1,14 +1,85 @@ package tests import ( + "context" "fmt" + "log" "os" "testing" + "time" + + "github.com/fnproject/fn/api/server" ) +func stopServer(done chan struct{}, stop func()) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + stop() + + select { + case <-done: + case <-ctx.Done(): + log.Panic("Server Cleanup failed, timeout") + } +} + +func startServer() (chan struct{}, func()) { + + log.Print("Starting server") + + ctx, srvCancel := context.WithCancel(context.Background()) + srvDone := make(chan struct{}) + + timeString := time.Now().Format("2006_01_02_15_04_05") + dbURL := os.Getenv(server.EnvDBURL) + tmpDir := os.TempDir() + tmpMq := fmt.Sprintf("%s/fn_integration_test_%s_worker_mq.db", tmpDir, timeString) + tmpDb := fmt.Sprintf("%s/fn_integration_test_%s_fn.db", tmpDir, timeString) + mqURL := fmt.Sprintf("bolt://%s", tmpMq) + if dbURL == "" { + dbURL = fmt.Sprintf("sqlite3://%s", tmpDb) + } + + srv := server.New(ctx, + server.WithLogLevel(getEnv(server.EnvLogLevel, server.DefaultLogLevel)), + server.WithDBURL(dbURL), + server.WithMQURL(mqURL), + server.WithFullAgent(), + ) + + go func() { + srv.Start(ctx) + log.Print("Stopped server") + os.Remove(tmpMq) + os.Remove(tmpDb) + close(srvDone) + }() + + startCtx, startCancel := context.WithDeadline(ctx, time.Now().Add(time.Duration(10)*time.Second)) + defer startCancel() + for { + err := checkServer(startCtx) + if err == nil { + break + } + select { + case <-time.After(time.Second * 1): + case <-ctx.Done(): + } + if ctx.Err() != nil { + log.Panic("Server check failed, timeout") + } + } + + return srvDone, srvCancel +} + func TestMain(m *testing.M) { + done, cancel := startServer() // call flag.Parse() here if TestMain uses flags result := m.Run() + stopServer(done, cancel) if result == 0 { fmt.Fprintln(os.Stdout, "😀 👍 🎗") diff --git a/test/fn-api-tests/utils.go b/test/fn-api-tests/utils.go index 84b9066db..b64bf1bc0 100644 --- a/test/fn-api-tests/utils.go +++ b/test/fn-api-tests/utils.go @@ -10,11 +10,9 @@ import ( "net/url" "os" "strings" - "sync" "testing" "time" - "github.com/fnproject/fn/api/server" "github.com/fnproject/fn_go/client" httptransport "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" @@ -76,107 +74,6 @@ func getEnv(key, fallback string) string { return fallback } -var ( - srvLock sync.Mutex - srvRefCount uint64 - srvInstance *server.Server - srvDone chan struct{} - srvCancel func() -) - -func stopServer(ctx context.Context) { - srvLock.Lock() - defer srvLock.Unlock() - if srvRefCount == 0 { - log.Printf("Server not running, ref count %v", srvRefCount) - return - } - - srvRefCount-- - if srvRefCount != 0 { - log.Printf("Server decrement ref count %v", srvRefCount) - return - } - - srvCancel() - - select { - case <-srvDone: - case <-ctx.Done(): - log.Panic("Server Cleanup failed, timeout") - } -} - -func startServer() { - - srvLock.Lock() - srvRefCount++ - - if srvRefCount != 1 { - log.Printf("Server already running, ref count %v", srvRefCount) - srvLock.Unlock() - - // check once - ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Duration(2)*time.Second)) - defer cancel() - err := checkServer(ctx) - if err != nil { - log.Panicf("Server check failed: %s", err) - } - - return - } - - log.Printf("Starting server, ref count %v", srvRefCount) - - srvDone = make(chan struct{}) - ctx, cancel := context.WithCancel(context.Background()) - srvCancel = cancel - - timeString := time.Now().Format("2006_01_02_15_04_05") - dbURL := os.Getenv(server.EnvDBURL) - tmpDir := os.TempDir() - tmpMq := fmt.Sprintf("%s/fn_integration_test_%s_worker_mq.db", tmpDir, timeString) - tmpDb := fmt.Sprintf("%s/fn_integration_test_%s_fn.db", tmpDir, timeString) - mqURL := fmt.Sprintf("bolt://%s", tmpMq) - if dbURL == "" { - dbURL = fmt.Sprintf("sqlite3://%s", tmpDb) - } - - srvInstance = server.New(ctx, - server.WithLogLevel(getEnv(server.EnvLogLevel, server.DefaultLogLevel)), - server.WithDBURL(dbURL), - server.WithMQURL(mqURL), - server.WithFullAgent(), - ) - - go func() { - srvInstance.Start(ctx) - log.Print("Stopped server") - os.Remove(tmpMq) - os.Remove(tmpDb) - close(srvDone) - }() - - srvLock.Unlock() - - startCtx, startCancel := context.WithDeadline(ctx, time.Now().Add(time.Duration(10)*time.Second)) - defer startCancel() - for { - err := checkServer(startCtx) - if err == nil { - break - } - select { - case <-time.After(time.Second * 1): - case <-ctx.Done(): - } - if ctx.Err() != nil { - log.Panic("Server check failed, timeout") - } - } -} - // TestHarness provides context and pre-configured clients to an individual test, it has some helper functions to create Apps and Routes that mirror the underlying client operations and clean them up after the test is complete // This is not goroutine safe and each test case should use its own harness. type TestHarness struct { @@ -209,8 +106,6 @@ func RandStringBytes(n int) string { func SetupHarness() *TestHarness { ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) - startServer() - ss := &TestHarness{ Context: ctx, Cancel: cancel, @@ -241,8 +136,6 @@ func (s *TestHarness) Cleanup() { for app, _ := range s.createdApps { safeDeleteApp(ctx, s.Client, app) } - - stopServer(ctx) } func EnvAsHeader(req *http.Request, selectedEnv []string) {