Skip to content

Commit dc55c62

Browse files
authored
acc: add -useversion flag for testing older versions (#3404)
## Changes New flag -useversion that downloads old version and uses it to run acceptance tests. ## Why Allows to quickly find out if a given behaviour is a regression. ## Tests Manually. For example, run current test suite on most recent release: `go test ./acceptance -useversion 0.263.0`
1 parent c16a1f0 commit dc55c62

File tree

1 file changed

+85
-1
lines changed

1 file changed

+85
-1
lines changed

acceptance/acceptance_test.go

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package acceptance_test
22

33
import (
4+
"archive/zip"
45
"bufio"
56
"context"
67
"encoding/base32"
@@ -44,6 +45,7 @@ var (
4445
LogRequests bool
4546
LogConfig bool
4647
SkipLocal bool
48+
UseVersion string
4749
)
4850

4951
// In order to debug CLI running under acceptance test, search for TestInprocessMode and update
@@ -64,6 +66,7 @@ func init() {
6466
flag.BoolVar(&LogRequests, "logrequests", false, "Log request and responses from testserver")
6567
flag.BoolVar(&LogConfig, "logconfig", false, "Log merged for each test case")
6668
flag.BoolVar(&SkipLocal, "skiplocal", false, "Skip tests that are enabled to run on Local")
69+
flag.StringVar(&UseVersion, "useversion", "", "Download previously released version of CLI and use it to run the tests")
6770
}
6871

6972
const (
@@ -166,7 +169,11 @@ func testAccept(t *testing.T, inprocessMode bool, singleTest string) int {
166169
t.Setenv("CMD_SERVER_URL", cmdServer.URL)
167170
execPath = filepath.Join(cwd, "bin", "callserver.py")
168171
} else {
169-
execPath = BuildCLI(t, buildDir, coverDir)
172+
if UseVersion != "" {
173+
execPath = DownloadCLI(t, buildDir, UseVersion)
174+
} else {
175+
execPath = BuildCLI(t, buildDir, coverDir)
176+
}
170177
}
171178

172179
BuildYamlfmt(t)
@@ -827,6 +834,83 @@ func BuildCLI(t *testing.T, buildDir, coverDir string) string {
827834
return execPath
828835
}
829836

837+
// DownloadCLI downloads a released CLI binary archive for the given version,
838+
// extracts the executable, and returns its path.
839+
func DownloadCLI(t *testing.T, buildDir, version string) string {
840+
// Prepare target directory for this version
841+
versionDir := filepath.Join(buildDir, version)
842+
require.NoError(t, os.MkdirAll(versionDir, 0o755))
843+
844+
execName := "databricks"
845+
if runtime.GOOS == "windows" {
846+
execName += ".exe"
847+
}
848+
execPath := filepath.Join(versionDir, execName)
849+
850+
// If already downloaded, reuse
851+
if _, err := os.Stat(execPath); err == nil {
852+
return execPath
853+
}
854+
855+
osName := runtime.GOOS
856+
archName := runtime.GOARCH
857+
858+
// Compose archive name per release naming scheme
859+
archiveName := fmt.Sprintf("databricks_cli_%s_%s_%s.zip", version, osName, archName)
860+
url := fmt.Sprintf("https://github.com/databricks/cli/releases/download/v%s/%s", version, archiveName)
861+
zipPath := filepath.Join(versionDir, archiveName)
862+
863+
downloadToFile(t, url, zipPath)
864+
extractFileFromZip(t, zipPath, execName, versionDir)
865+
866+
return execPath
867+
}
868+
869+
// downloadToFile downloads contents from url into the given destination path
870+
func downloadToFile(t *testing.T, url, destPath string) {
871+
require.NoError(t, os.MkdirAll(filepath.Dir(destPath), 0o755))
872+
out, err := os.Create(destPath)
873+
require.NoError(t, err)
874+
defer out.Close()
875+
876+
resp, err := http.Get(url)
877+
require.NoError(t, err)
878+
defer resp.Body.Close()
879+
require.Equal(t, http.StatusOK, resp.StatusCode, "failed to download %s: %s", url, resp.Status)
880+
881+
_, err = io.Copy(out, resp.Body)
882+
require.NoError(t, err)
883+
}
884+
885+
// extractFileFromZip finds a file by name inside a zip archive and writes it
886+
// into destDir using the file's base name. Fails the test if not found.
887+
func extractFileFromZip(t *testing.T, zipPath, fileName, destDir string) {
888+
r, err := zip.OpenReader(zipPath)
889+
require.NoError(t, err)
890+
defer r.Close()
891+
892+
targetBase := filepath.Base(fileName)
893+
destPath := filepath.Join(destDir, targetBase)
894+
var found bool
895+
for _, f := range r.File {
896+
if filepath.Base(f.Name) != targetBase {
897+
continue
898+
}
899+
rc, err := f.Open()
900+
require.NoError(t, err)
901+
defer rc.Close()
902+
903+
out, err := os.OpenFile(destPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o755)
904+
require.NoError(t, err)
905+
_, err = io.Copy(out, rc)
906+
_ = out.Close()
907+
require.NoError(t, err)
908+
found = true
909+
break
910+
}
911+
require.True(t, found, "file %s not found in archive %s", targetBase, zipPath)
912+
}
913+
830914
func copyFile(src, dst string) error {
831915
in, err := os.Open(src)
832916
if err != nil {

0 commit comments

Comments
 (0)