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

Test against 8.10 on main with the 8.11 agent by editing the package version #3277

Closed
wants to merge 4 commits into from
Closed
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
20 changes: 19 additions & 1 deletion magefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ import (
)

const (
VersionAgentStack = "AGENT_STACK_VERSION"

goLintRepo = "golang.org/x/lint/golint"
goLicenserRepo = "github.com/elastic/go-licenser"
buildDir = "build"
Expand Down Expand Up @@ -1683,7 +1685,8 @@ func createTestRunner(matrix bool, singleTest string, goTestFlags string, batche
if err != nil {
return nil, err
}
agentStackVersion := os.Getenv("AGENT_STACK_VERSION")

agentStackVersion := os.Getenv(VersionAgentStack)
agentVersion := os.Getenv("AGENT_VERSION")
if agentVersion == "" {
agentVersion, err = mage.DefaultBeatBuildVariableSources.GetBeatVersion()
Expand All @@ -1703,6 +1706,21 @@ func createTestRunner(matrix bool, singleTest string, goTestFlags string, batche
if agentStackVersion == "" {
agentStackVersion = agentVersion
}

pv, err := version.ParseVersion(agentStackVersion)
if err != nil {
return nil, fmt.Errorf("could not parse agentStackVersion %q: %w",
agentStackVersion, err)
}
if pv.Major() == 8 && pv.Minor() == 11 {
prev, err := pv.GetPreviousMinor()
if err != nil {
return nil, fmt.Errorf("8.11 cannoit be used right now, "+
"failed getting previous minor: %w", err)
}
agentStackVersion = prev.String()
}

agentBuildDir := os.Getenv("AGENT_BUILD_DIR")
if agentBuildDir == "" {
agentBuildDir = filepath.Join("build", "distributions")
Expand Down
68 changes: 68 additions & 0 deletions pkg/testing/fixture.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"encoding/json"
"errors"
"fmt"
"io/fs"
"io/ioutil"
"os"
"os/exec"
Expand All @@ -29,6 +30,8 @@ import (
"github.com/elastic/elastic-agent/pkg/control/v2/client"
"github.com/elastic/elastic-agent/pkg/control/v2/cproto"
"github.com/elastic/elastic-agent/pkg/core/process"
"github.com/elastic/elastic-agent/pkg/version"
agentVersion "github.com/elastic/elastic-agent/version"
)

// Fixture handles the setup and management of the Elastic Agent.
Expand Down Expand Up @@ -127,6 +130,7 @@ func NewFixture(t *testing.T, version string, opts ...FixtureOpt) (*Fixture, err
for _, o := range opts {
o(f)
}

return f, nil
}

Expand Down Expand Up @@ -175,7 +179,71 @@ func (f *Fixture) Prepare(ctx context.Context, components ...UsableComponent) er
if err != nil {
return err
}

f.workDir = finalDir

err = decreasePackageVersionDuringFeatureFreeze(f, f.workDir)
if err != nil {
return err
}

return nil
}

// After feature freeze the agent has the version of the next minor but there is a few
// days of lag until the snapshot is produced to test against. To get around this the
// tests continue to provision the previous minor and the agent package version is replaced
// to report the previous minor version as well. As of the time of writing fleet server
// will consider versions greater than its own to be unsupported. This allows the newer
// agent to enroll.
//
// This function is meant to be temporary. Fleet server should be modified to allow the next
// minor version to connect to get around this in a more sustainable way.
func decreasePackageVersionDuringFeatureFreeze(f *Fixture, workDir string) error {
installFS := os.DirFS(workDir)
var matches []string
err := fs.WalkDir(installFS, ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return fmt.Errorf("my fs.WalkDir reveiced and error and aborted: %w",
err)
}

if d.Name() == agentVersion.PackageVersionFileName {
matches = append(matches, path)
}
return nil
})
if err != nil {
return err
}

f.t.Logf("package version files found: %v\n", matches)

for _, m := range matches {
versionFile := filepath.Join(f.WorkDir(), m)

pv, err := version.ParseVersion(f.version)
if err != nil {
return fmt.Errorf("could not parse fixture version: %w", err)
}

if pv.Major() == 8 && pv.Minor() == 11 {
prev, err := pv.GetPreviousMinor()
if err != nil {
return fmt.Errorf("8.11 cannot be used right now, "+
"failed getting previous minor: %w", err)
}

err = os.WriteFile(versionFile, []byte(prev.String()), 0666)
if err != nil {
return fmt.Errorf("could not write package-version file %q: %w",
versionFile, err)
}

f.t.Logf("Updated package version file from %s to %s", pv.String(), prev.String())
}
}

return nil
}

Expand Down
18 changes: 15 additions & 3 deletions pkg/testing/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,11 @@ func (r *Runner) Clean() error {
}

// runInstances runs the batch on each instance in parallel.
func (r *Runner) runInstances(ctx context.Context, sshAuth ssh.AuthMethod, repoArchive string, instances []StateInstance) (map[string]OSRunnerResult, error) {
func (r *Runner) runInstances(
ctx context.Context,
sshAuth ssh.AuthMethod,
repoArchive string,
instances []StateInstance) (map[string]OSRunnerResult, error) {
g, ctx := errgroup.WithContext(ctx)
results := make(map[string]OSRunnerResult)
var resultsMx sync.Mutex
Expand Down Expand Up @@ -315,7 +319,13 @@ func (r *Runner) runInstances(ctx context.Context, sshAuth ssh.AuthMethod, repoA
}

// runInstance runs the batch on the machine.
func (r *Runner) runInstance(ctx context.Context, sshAuth ssh.AuthMethod, logger Logger, repoArchive string, batch OSBatch, instance StateInstance) (OSRunnerResult, error) {
func (r *Runner) runInstance(
ctx context.Context,
sshAuth ssh.AuthMethod,
logger Logger,
repoArchive string,
batch OSBatch,
instance StateInstance) (OSRunnerResult, error) {
sshPrivateKeyPath, err := filepath.Abs(filepath.Join(r.cfg.StateDir, "id_rsa"))
if err != nil {
return OSRunnerResult{}, fmt.Errorf("failed to determine OGC SSH private key path: %w", err)
Expand Down Expand Up @@ -368,7 +378,9 @@ func (r *Runner) runInstance(ctx context.Context, sshAuth ssh.AuthMethod, logger
// wait for the stack to be ready before continuing
r.stacksReady.Wait()
if r.stacksErr != nil {
return OSRunnerResult{}, fmt.Errorf("%s unable to continue because stack never became ready: %w", instance.Name, r.stacksErr)
return OSRunnerResult{}, fmt.Errorf(
"%s unable to continue because stack never became ready: %w",
instance.Name, r.stacksErr)
}
stack, ok := r.getStackForBatchID(batch.ID)
if !ok {
Expand Down
7 changes: 4 additions & 3 deletions pkg/version/version_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,16 +113,17 @@ func (psv ParsedSemVer) GetPreviousMinor() (*ParsedSemVer, error) {

if minor > 0 {
// We have at least one previous minor version in the current
// major version series
return NewParsedSemVer(major, minor-1, 0, "", ""), nil
// major version series. Set the patch to zero to guarnatee the
// version exists, the number of patch releases varies.
return NewParsedSemVer(major, minor-1, 0, psv.Prerelease(), psv.BuildMetadata()), nil
}

// We are at the first minor of the current major version series. To
// figure out the previous minor, we need to rely on knowledge of
// the release versions from the past major series'.
switch major {
case 8:
return NewParsedSemVer(7, 17, 10, "", ""), nil
return NewParsedSemVer(7, 17, 10, psv.Prerelease(), psv.BuildMetadata()), nil
}

return nil, fmt.Errorf("unable to determine previous minor version for [%s]", psv.String())
Expand Down
51 changes: 51 additions & 0 deletions pkg/version/version_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -360,3 +360,54 @@ func TestLess(t *testing.T) {
})
}
}

func TestPreviousMinor(t *testing.T) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GetPrevMinor method was discarding the prerelease and build metadata information.

testcases := []struct {
name string
version string
prevMinorVersion string
}{
{
name: "basic release version",
version: "8.7.0",
prevMinorVersion: "8.6.0",
},
{
name: "snapshot release version",
version: "8.9.3-SNAPSHOT",
prevMinorVersion: "8.8.0-SNAPSHOT",
},
{
name: "emergency release version",
version: "8.9.0-er1",
prevMinorVersion: "8.8.0-er1",
},
{
name: "previous major version",
version: "8.0.0",
prevMinorVersion: "7.17.10",
},
{
name: "previous major snapshot",
version: "8.0.0-SNAPSHOT",
prevMinorVersion: "7.17.10-SNAPSHOT",
},
{
name: "snapshot version with metadata",
version: "8.9.1-SNAPSHOT+aaaaaa",
prevMinorVersion: "8.8.0-SNAPSHOT+aaaaaa",
},
}

for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
parsed, err := ParseVersion(tc.version)
require.NoError(t, err)
require.NotNil(t, parsed)

prev, err := parsed.GetPreviousMinor()
require.NoError(t, err)
require.Equal(t, tc.prevMinorVersion, prev.String())
})
}
}
Loading