Skip to content

Commit

Permalink
Add 1 independent release into upgrade matrix (#6075)
Browse files Browse the repository at this point in the history
(cherry picked from commit a4bf7d0)

# Conflicts:
#	testing/integration/testdata/.upgrade-test-agent-versions.yml
  • Loading branch information
michalpristas authored and mergify[bot] committed Nov 29, 2024
1 parent 171ff75 commit 44a9570
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 7 deletions.
10 changes: 5 additions & 5 deletions pkg/testing/fetcher_artifact.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,13 @@ func (r *artifactResult) Fetch(ctx context.Context, l Logger, dir string) error
}

func findURI(ctx context.Context, doer httpDoer, version *semver.ParsedSemVer) (string, error) {
// if we know the exact build ID, we can build the URI right away
if version.BuildMetadata() != "" {
return fmt.Sprintf("https://snapshots.elastic.co/%s-%s/downloads/beats/elastic-agent/", version.CoreVersion(), version.BuildMetadata()), nil
}

// if it's the latest snapshot of a version, we can find a build ID and build the URI in the same manner
if version.IsSnapshot() {
// if we know the exact build ID, we can build the URI right away
if version.BuildMetadata() != "" {
return fmt.Sprintf("https://snapshots.elastic.co/%s-%s/downloads/beats/elastic-agent/", version.CoreVersion(), version.BuildMetadata()), nil
}

buildID, err := findLatestSnapshot(ctx, doer, version.CoreVersion())
if err != nil {
return "", fmt.Errorf("failed to find snapshot information for version %q: %w", version, err)
Expand Down
39 changes: 39 additions & 0 deletions pkg/version/version_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const preReleaseSeparator = "-"
const metadataSeparator = "+"
const prereleaseTokenSeparator = "."
const snapshotPrereleaseToken = "SNAPSHOT"
const IsIndependentReleaseFormat = `^build\d{12}`

var semVerFmtRegEx *regexp.Regexp
var numericPrereleaseTokenRegEx *regexp.Regexp
Expand Down Expand Up @@ -129,6 +130,20 @@ func (psv ParsedSemVer) IsSnapshot() bool {
return slices.Contains(prereleaseTokens, snapshotPrereleaseToken)
}

func (psv ParsedSemVer) IsIndependentRelease() bool {
matched, err := regexp.MatchString(IsIndependentReleaseFormat, psv.buildMetadata)
return err == nil && matched
}

func (psv ParsedSemVer) IndependentBuildID() string {
r := regexp.MustCompile(IsIndependentReleaseFormat)
if matches := r.FindAllString(psv.buildMetadata, -1); len(matches) > 0 {
return matches[0]
}

return ""
}

func (psv ParsedSemVer) Less(other ParsedSemVer) bool {
// compare major version
if psv.major != other.major {
Expand All @@ -145,10 +160,33 @@ func (psv ParsedSemVer) Less(other ParsedSemVer) bool {
return psv.patch < other.patch
}

if psv.IsIndependentRelease() || other.IsIndependentRelease() {
// one of them is independent release let's compare those
return psv.compareIndependentBuild(other)
}

// compare prerelease strings as major.minor.patch are equal
return psv.comparePrerelease(other)
}

func (psv ParsedSemVer) compareIndependentBuild(other ParsedSemVer) bool {
// spare regex parsing
psvIsIndependent := psv.IsIndependentRelease()
otherIsIndependent := other.IsIndependentRelease()

if !psvIsIndependent && !otherIsIndependent {
return false
}

if psvIsIndependent != otherIsIndependent {
// independent release is always newer
return !psvIsIndependent
}

// compare build IDs
return psv.IndependentBuildID() < other.IndependentBuildID()
}

// comparePrerelease compares the prerelease part of 2 ParsedSemVer objects
// the return value must conform to psv.prerelease < other.prerelease following comparison rules from https://semver.org/
func (psv ParsedSemVer) comparePrerelease(other ParsedSemVer) bool {
Expand Down Expand Up @@ -251,6 +289,7 @@ func ParseVersion(version string) (*ParsedSemVer, error) {
if err != nil {
return nil, fmt.Errorf("parsing patch version: %w", err)
}

return &ParsedSemVer{
original: version,
major: major,
Expand Down
93 changes: 93 additions & 0 deletions pkg/version/version_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package version

import (
"fmt"
"strings"
"testing"

Expand Down Expand Up @@ -296,6 +297,72 @@ func TestIsSnapshot(t *testing.T) {

}

func TestIsIndependentRelease(t *testing.T) {
testcases := []struct {
name string
input string
expected bool
}{
{
name: "Simple version",
input: "8.8.0",
expected: false,
},
{
name: "Simple snapshot",
input: "8.8.0-SNAPSHOT",
expected: false,
},
{
name: "Independent release",
input: "8.8.0+build20241224081012",
expected: true,
},
{
name: "Independent release no time",
input: "8.8.0+build20241224",
expected: false,
},
{
name: "Independent release and more",
input: "8.8.0+build20241224081012.meta.5",
expected: true,
},
}

for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
psv, err := ParseVersion(tc.input)
require.NoError(t, err)
require.NotNil(t, psv)
assert.Equal(t, tc.expected, psv.IsIndependentRelease())
})
}
}

func TestIndependenBuild(t *testing.T) {
testCases := []struct {
Version string
ExpectedBuildID string
}{
{"8.10.9", ""},
{"8.10.9-SNAPSHOT", ""},
{"1.2.3-er.1+abcdef", ""},
{"8.10.9+build20241224", ""},
{"8.10.9+build202412240810", "build202412240810"},
{"8.10.9+build202412240810.meta.5", "build202412240810"},
}

for i, tc := range testCases {
t.Run(fmt.Sprintf("#%d %s", i, tc.Version), func(t *testing.T) {
pv, err := ParseVersion(tc.Version)
assert.NoError(t, err)

assert.Equal(t, tc.ExpectedBuildID, pv.IndependentBuildID())
})
}
}

func TestExtractSnapshotFromVersionString(t *testing.T) {
testcases := []struct {
name string
Expand Down Expand Up @@ -476,6 +543,32 @@ func TestLess(t *testing.T) {
rightVersion: "1.0.0",
less: true,
},

// independent section
{
name: "independent release is always more than regular",
leftVersion: "8.9.0+build202405061022",
rightVersion: "8.9.0",
less: false,
},
{
name: "prerelease is less than independent release",
leftVersion: "8.9.0-SNAPSHOT",
rightVersion: "8.9.0+build202405061022",
less: true,
},
{
name: "older release is less",
leftVersion: "8.9.0+build202305061022",
rightVersion: "8.9.0+build202405061022",
less: true,
},
{
name: "older release is less - reversed",
leftVersion: "8.9.0+build202405061022",
rightVersion: "8.9.0+build202305061022",
less: false,
},
}

for _, tc := range testcases {
Expand Down
5 changes: 5 additions & 0 deletions testing/integration/testdata/.upgrade-test-agent-versions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@
# upgrade integration tests.

testVersions:
<<<<<<< HEAD
- 8.17.0-SNAPSHOT
- 8.16.0-SNAPSHOT
- 8.15.3
- 8.14.3
=======
- 8.16.0
- 8.15.4
>>>>>>> a4bf7d07bf (Add 1 independent release into upgrade matrix (#6075))
- 7.17.26-SNAPSHOT
- 7.17.25
3 changes: 1 addition & 2 deletions testing/upgradetest/versions.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ func findRequiredVersions(sortedParsedVersions []*version.ParsedSemVer, reqs Ver
previousMajorsToFind := reqs.PreviousMajors
previousMinorsToFind := reqs.PreviousMinors
recentSnapshotsToFind := len(reqs.SnapshotBranches)

for _, version := range sortedParsedVersions {
switch {
// we skip version above the target
Expand All @@ -200,7 +199,7 @@ func findRequiredVersions(sortedParsedVersions []*version.ParsedSemVer, reqs Ver
recentSnapshotsToFind--

// for the rest of the checks we capture only released versions
case version.Prerelease() != "" || version.BuildMetadata() != "":
case version.Prerelease() != "" || (version.BuildMetadata() != "" && !version.IsIndependentRelease()):
continue

// previous minors
Expand Down

0 comments on commit 44a9570

Please sign in to comment.