From 1f1d705de9967fa902298e66721774583d4a3d4f Mon Sep 17 00:00:00 2001 From: Shreyas Goenka Date: Wed, 29 Jan 2025 14:51:36 +0100 Subject: [PATCH] move config to toml --- acceptance/acceptance_test.go | 19 +++++-- acceptance/config_test.go | 4 ++ acceptance/workspace/jobs/create/server.json | 11 ---- acceptance/workspace/jobs/create/test.toml | 7 +++ libs/testserver/server.go | 60 ++++---------------- 5 files changed, 37 insertions(+), 64 deletions(-) delete mode 100644 acceptance/workspace/jobs/create/server.json create mode 100644 acceptance/workspace/jobs/create/test.toml diff --git a/acceptance/acceptance_test.go b/acceptance/acceptance_test.go index 318d20515..38218b32d 100644 --- a/acceptance/acceptance_test.go +++ b/acceptance/acceptance_test.go @@ -2,10 +2,12 @@ package acceptance_test import ( "context" + "encoding/json" "errors" "flag" "fmt" "io" + "net/http" "os" "os/exec" "path/filepath" @@ -30,7 +32,7 @@ var KeepTmp bool // In order to debug CLI running under acceptance test, set this to full subtest name, e.g. "bundle/variables/empty" // Then install your breakpoints and click "debug test" near TestAccept in VSCODE. // example: var SingleTest = "bundle/variables/empty" -var SingleTest = "" +var SingleTest = "workspace/jobs/create" // If enabled, instead of compiling and running CLI externally, we'll start in-process server that accepts and runs // CLI commands. The $CLI in test scripts is a helper that just forwards command-line arguments to this server (see bin/callserver.py). @@ -205,10 +207,17 @@ func runTest(t *testing.T, dir, coverDir string, repls testdiff.ReplacementsCont cmdEnv := os.Environ() - // If there is a server.json file in the test directory, start a custom server. - // Redirect all API calls to this server. - if testutil.DetectFile(t, filepath.Join(dir, "server.json")) { - server := testserver.NewFromConfig(t, filepath.Join(dir, "server.json")) + // Load custom server stubs configured for the integration test. + if len(config.Server) > 0 { + server := testserver.New(t) + for _, stub := range config.Server { + require.NotEmpty(t, stub.Pattern) + require.NotEmpty(t, stub.Response.Body) + server.Handle(stub.Pattern, func(req *http.Request) (resp any, err error) { + b := json.RawMessage(stub.Response.Body) + return b, nil + }) + } cmdEnv = setEnv(cmdEnv, "DATABRICKS_HOST", server.URL) t.Cleanup(func() { server.Close() diff --git a/acceptance/config_test.go b/acceptance/config_test.go index 41866c4a7..d6713998e 100644 --- a/acceptance/config_test.go +++ b/acceptance/config_test.go @@ -8,6 +8,7 @@ import ( "github.com/BurntSushi/toml" "github.com/databricks/cli/libs/testdiff" + "github.com/databricks/cli/libs/testserver" "github.com/stretchr/testify/require" ) @@ -29,6 +30,9 @@ type TestConfig struct { // List of additional replacements to apply on this test. // Old is a regexp, New is a replacement expression. Repls []testdiff.Replacement + + // List of server stubs to load. + Server []testserver.Stub } // FindConfig finds the closest config file. diff --git a/acceptance/workspace/jobs/create/server.json b/acceptance/workspace/jobs/create/server.json deleted file mode 100644 index 79eb75aac..000000000 --- a/acceptance/workspace/jobs/create/server.json +++ /dev/null @@ -1,11 +0,0 @@ -[ - { - "method": "POST", - "path": "/api/2.1/jobs/create", - "response": { - "body": { - "job_id": 1111 - } - } - } -] diff --git a/acceptance/workspace/jobs/create/test.toml b/acceptance/workspace/jobs/create/test.toml new file mode 100644 index 000000000..94e5eee13 --- /dev/null +++ b/acceptance/workspace/jobs/create/test.toml @@ -0,0 +1,7 @@ +[[Server]] +Pattern = "POST /api/2.1/jobs/create" +Response.Body = ''' +{ + "job_id": 1111 +} +''' diff --git a/libs/testserver/server.go b/libs/testserver/server.go index 4377ebe71..711d20561 100644 --- a/libs/testserver/server.go +++ b/libs/testserver/server.go @@ -6,8 +6,6 @@ import ( "net/http/httptest" "github.com/databricks/cli/internal/testutil" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) type Server struct { @@ -15,17 +13,18 @@ type Server struct { Mux *http.ServeMux t testutil.TestingT - - // API calls that we expect to be made. - calledPatterns map[string]bool } -type ApiSpec struct { - Method string `json:"method"` - Path string `json:"path"` +type Stub struct { + // The HTTP method and path to match. Examples: + // 1. /api/2.0/clusters/list (matches all methods) + // 2. GET /api/2.0/clusters/list + Pattern string + + // The response body to return. Response struct { - Body json.RawMessage `json:"body"` - } `json:"response"` + Body string + } } func New(t testutil.TestingT) *Server { @@ -33,50 +32,15 @@ func New(t testutil.TestingT) *Server { server := httptest.NewServer(mux) return &Server{ - Server: server, - Mux: mux, - t: t, - calledPatterns: make(map[string]bool), + Server: server, + Mux: mux, + t: t, } } -func NewFromConfig(t testutil.TestingT, path string) *Server { - content := testutil.ReadFile(t, path) - var apiSpecs []ApiSpec - err := json.Unmarshal([]byte(content), &apiSpecs) - require.NoError(t, err) - - server := New(t) - for _, apiSpec := range apiSpecs { - server.MustHandle(apiSpec) - } - - return server -} - type HandlerFunc func(req *http.Request) (resp any, err error) -func (s *Server) MustHandle(apiSpec ApiSpec) { - assert.NotEmpty(s.t, apiSpec.Method) - assert.NotEmpty(s.t, apiSpec.Path) - - pattern := apiSpec.Method + " " + apiSpec.Path - s.calledPatterns[pattern] = false - - s.Handle(pattern, func(req *http.Request) (any, error) { - // Record the fact that this pattern was called. - s.calledPatterns[pattern] = true - - // Return the expected response body. - return apiSpec.Response.Body, nil - }) -} - func (s *Server) Close() { - for pattern, called := range s.calledPatterns { - assert.Truef(s.t, called, "expected pattern %s to be called", pattern) - } - s.Server.Close() }