Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add integration test upgrading latest release to a build from the current PR #5457

Merged
merged 17 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ func prepareTestCase(t *testing.T, a artifact.Artifact, version *agtversion.Pars
err = os.WriteFile(filePathSHA, []byte(hashContent), 0644)
require.NoErrorf(t, err, "could not write %q file", filePathSHA)

pub, sig := pgptest.Sing(t, bytes.NewReader(content))
pub, sig := pgptest.Sign(t, bytes.NewReader(content))
err = os.WriteFile(filePathASC, sig, 0644)
require.NoErrorf(t, err, "could not write %q file", filePathASC)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func getElasticCoServer(t *testing.T) (*httptest.Server, []byte) {
var resp []byte
content := []byte("anything will do")
hash := sha512.Sum512(content)
pub, sig := pgptest.Sing(t, bytes.NewReader(content))
pub, sig := pgptest.Sign(t, bytes.NewReader(content))

handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
packageName := r.URL.Path[len(sourcePattern):]
Expand Down
77 changes: 71 additions & 6 deletions pkg/testing/fixture.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ type Fixture struct {

// Uninstall token value that is needed for the agent uninstall if it's tamper protected
uninstallToken string

// fileNamePrefix is a prefix to be used when saving files from this test.
// it's set by FileNamePrefix and once it's set, FileNamePrefix will return
// its value.
fileNamePrefix string
AndersonQ marked this conversation as resolved.
Show resolved Hide resolved
}

// FixtureOpt is an option for the fixture.
Expand Down Expand Up @@ -1010,16 +1015,13 @@ func (f *Fixture) setClient(c client.Client) {

func (f *Fixture) DumpProcesses(suffix string) {
procs := getProcesses(f.t, `.*`)
dir, err := findProjectRoot(f.caller)
dir, err := f.DiagnosticsDir()
if err != nil {
f.t.Logf("failed to dump process; failed to find project root: %s", err)
f.t.Logf("failed to dump process: %s", err)
return
}

// Sub-test names are separated by "/" characters which are not valid filenames on Linux.
sanitizedTestName := strings.ReplaceAll(f.t.Name(), "/", "-")

filePath := filepath.Join(dir, "build", "diagnostics", fmt.Sprintf("TEST-%s-%s-%s-ProcessDump%s.json", sanitizedTestName, f.operatingSystem, f.architecture, suffix))
filePath := filepath.Join(dir, fmt.Sprintf("%s-ProcessDump%s.json", f.FileNamePrefix(), suffix))
fileDir := path.Dir(filePath)
if err := os.MkdirAll(fileDir, 0777); err != nil {
f.t.Logf("failed to dump process; failed to create directory %s: %s", fileDir, err)
Expand All @@ -1044,6 +1046,69 @@ func (f *Fixture) DumpProcesses(suffix string) {
}
}

// MoveToDiagnosticsDir moves file to 'build/diagnostics' which contents are
// available on CI if the test fails or on the agent's 'build/diagnostics'
// if the test is run locally.
// If the file name does nos start with Fixture.FileNamePrefix(), it'll be added
// to the filename when moving.
func (f *Fixture) MoveToDiagnosticsDir(file string) {
dir, err := f.DiagnosticsDir()
if err != nil {
f.t.Logf("failed to move file to diagnostcs directory: %s", err)
return
}

filename := filepath.Base(file)
if !strings.HasPrefix(filename, f.FileNamePrefix()) {
filename = fmt.Sprintf("%s-%s", f.FileNamePrefix(), filename)
}
destFile := filepath.Join(dir, filename)

f.t.Logf("moving %q to %q", file, destFile)
err = os.Rename(file, destFile)
if err != nil {
f.t.Logf("failed to move %q to %q: %v", file, destFile, err)
}
}

// FileNamePrefix returns a sanitized and unique name to be used as prefix for
// files to be kept as resources for investigation when the test fails.
func (f *Fixture) FileNamePrefix() string {
if f.fileNamePrefix != "" {
return f.fileNamePrefix
}

stamp := time.Now().Format(time.RFC3339)
// on Windows a filename cannot contain a ':' as this collides with disk
// labels (aka. C:\)
stamp = strings.ReplaceAll(stamp, ":", "-")

// Subtest names are separated by "/" characters which are not valid
// filenames on Linux.
sanitizedTestName := strings.ReplaceAll(f.t.Name(), "/", "-")
prefix := fmt.Sprintf("%s-%s", sanitizedTestName, stamp)

f.fileNamePrefix = prefix
return f.fileNamePrefix
}

// DiagnosticsDir returned {projectRoot}/build/diagnostics path. Files on this path
// are saved if any test fails. Use it to save files for further investigation.
func (f *Fixture) DiagnosticsDir() (string, error) {
dir, err := findProjectRoot(f.caller)
if err != nil {
return "", fmt.Errorf("failed to find project root: %w", err)
}

diagPath := filepath.Join(dir, "build", "diagnostics")

if err := os.MkdirAll(diagPath, 0777); err != nil {
return "", fmt.Errorf("failed to create directory %s: %w", diagPath, err)
}

return diagPath, nil
}

// validateComponents ensures that the provided UsableComponent's are valid.
func validateComponents(components ...UsableComponent) error {
for idx, comp := range components {
Expand Down
28 changes: 4 additions & 24 deletions pkg/testing/fixture_install.go
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ func (f *Fixture) collectDiagnostics() {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()

diagPath, err := f.DiagDir()
diagPath, err := f.DiagnosticsDir()
if err != nil {
f.t.Logf("failed to collect diagnostics: %v", err)
return
Expand All @@ -661,15 +661,8 @@ func (f *Fixture) collectDiagnostics() {
return
}

stamp := time.Now().Format(time.RFC3339)
if runtime.GOOS == "windows" {
// on Windows a filename cannot contain a ':' as this collides with disk labels (aka. C:\)
stamp = strings.ReplaceAll(stamp, ":", "-")
}

// Sub-test names are separated by "/" characters which are not valid filenames on Linux.
sanitizedTestName := strings.ReplaceAll(f.t.Name(), "/", "-")
outputPath := filepath.Join(diagPath, fmt.Sprintf("%s-diagnostics-%s.zip", sanitizedTestName, stamp))
prefix := f.FileNamePrefix()
outputPath := filepath.Join(diagPath, prefix+"-diagnostics.zip")

output, err := f.Exec(ctx, []string{"diagnostics", "-f", outputPath})
if err != nil {
Expand All @@ -689,8 +682,7 @@ func (f *Fixture) collectDiagnostics() {
if err != nil {
// If collecting diagnostics fails, zip up the entire installation directory with the hope that it will contain logs.
f.t.Logf("creating zip archive of the installation directory: %s", f.workDir)
timestamp := strings.ReplaceAll(time.Now().Format(time.RFC3339), ":", "-")
zipPath := filepath.Join(diagPath, fmt.Sprintf("%s-install-directory-%s.zip", sanitizedTestName, timestamp))
zipPath := filepath.Join(diagPath, fmt.Sprintf("%s-install-directory.zip", prefix))
err = f.archiveInstallDirectory(f.workDir, zipPath)
if err != nil {
f.t.Logf("failed to zip install directory to %s: %s", zipPath, err)
Expand All @@ -699,18 +691,6 @@ func (f *Fixture) collectDiagnostics() {
}
}

// DiagDir returned {projectRoot}/build/diagnostics path. Files on this path
// are saved if any test fails. Use it to save files for further investigation.
func (f *Fixture) DiagDir() (string, error) {
dir, err := findProjectRoot(f.caller)
if err != nil {
return "", fmt.Errorf("failed to find project root: %w", err)
}

diagPath := filepath.Join(dir, "build", "diagnostics")
return diagPath, nil
}

func (f *Fixture) archiveInstallDirectory(installPath string, outputPath string) error {
file, err := os.Create(outputPath)
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions testing/integration/groups_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ const (
// privileged and airgapped.
FleetAirgappedPrivileged = "fleet-airgapped-privileged"

// FleetUpgradeToPRBuild group of tests. Used for testing Elastic Agent
// upgrading to a build built from the PR being tested.
FleetUpgradeToPRBuild = "fleet-upgrade-to-pr-build"

// FQDN group of tests. Used for testing Elastic Agent with FQDN enabled.
FQDN = "fqdn"

Expand Down
2 changes: 1 addition & 1 deletion testing/integration/package_version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ func TestComponentBuildHashInDiagnostics(t *testing.T) {
}

t.Logf("the test failed: trying to save the diagnostics used on the test")
diagDir, err := f.DiagDir()
diagDir, err := f.DiagnosticsDir()
if err != nil {
t.Logf("could not get diagnostics directory to save the diagnostics used on the test")
return
Expand Down
Loading