Skip to content

Commit 4fd31f1

Browse files
authored
add a DEB integration test (#4301)
* add a DEB integration test
1 parent 347a720 commit 4fd31f1

19 files changed

+446
-153
lines changed

.buildkite/scripts/steps/integration_tests.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ else
1919
OVERRIDE_TEST_AGENT_VERSION=""
2020
fi
2121
# PACKAGE
22-
AGENT_PACKAGE_VERSION="${OVERRIDE_AGENT_PACKAGE_VERSION}" DEV=true EXTERNAL=true SNAPSHOT=true PLATFORMS=linux/amd64,linux/arm64,windows/amd64 PACKAGES=tar.gz,zip mage package
22+
AGENT_PACKAGE_VERSION="${OVERRIDE_AGENT_PACKAGE_VERSION}" DEV=true EXTERNAL=true SNAPSHOT=true PLATFORMS=linux/amd64,linux/arm64,windows/amd64 PACKAGES=tar.gz,zip,rpm,deb mage package
2323

2424
# Run integration tests
2525
set +e

dev-tools/mage/pkg.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func Package() error {
3434
// platforms := updateWithDarwinUniversal(Platforms)
3535
platforms := Platforms
3636

37-
var tasks []interface{}
37+
tasks := make(map[string][]interface{})
3838
for _, target := range platforms {
3939
for _, pkg := range Packages {
4040
if pkg.OS != target.GOOS() || pkg.Arch != "" && pkg.Arch != target.Arch() {
@@ -94,12 +94,15 @@ func Package() error {
9494

9595
spec = spec.Evaluate()
9696

97-
tasks = append(tasks, packageBuilder{target, spec, pkgType}.Build)
97+
tasks[target.GOOS()+"-"+target.Arch()] = append(tasks[target.GOOS()+"-"+target.Arch()], packageBuilder{target, spec, pkgType}.Build)
9898
}
9999
}
100100
}
101101

102-
Parallel(tasks...)
102+
for k, v := range tasks {
103+
fmt.Printf(">> package: Building %s\n", k)
104+
Parallel(v...)
105+
}
103106
return nil
104107
}
105108

pkg/testing/define/define.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ func runOrSkip(t *testing.T, req Requirements, local bool) *Info {
151151
panic("failed to get OS information")
152152
}
153153
if !req.runtimeAllowed(runtime.GOOS, runtime.GOARCH, osInfo.Version, osInfo.Platform) {
154-
t.Skip("platform, architecture, version, and distro not supported by test")
154+
t.Skipf("platform: %s, architecture: %s, version: %s, and distro: %s combination is not supported by test. required: %v", runtime.GOOS, runtime.GOARCH, osInfo.Version, osInfo.Platform, req.OS)
155155
return nil
156156
}
157157
namespace, err := getNamespace(t, local)

pkg/testing/fetch_test.go

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
2+
// or more contributor license agreements. Licensed under the Elastic License;
3+
// you may not use this file except in compliance with the Elastic License.
4+
5+
package testing
6+
7+
import (
8+
"errors"
9+
gtesting "testing"
10+
)
11+
12+
func TestGetPackageSuffix(t *gtesting.T) {
13+
tests := map[string]struct {
14+
os string
15+
arch string
16+
format string
17+
expected string
18+
err error
19+
}{
20+
"windows zip": {os: "windows", arch: "amd64", format: "zip", expected: "windows-x86_64.zip", err: nil},
21+
"windows msi": {os: "windows", arch: "amd64", format: "msi", expected: "", err: ErrUnsupportedPlatform},
22+
"linux deb": {os: "linux", arch: "amd64", format: "deb", expected: "amd64.deb", err: nil},
23+
"linux rpm": {os: "linux", arch: "amd64", format: "rpm", expected: "x86_64.rpm", err: nil},
24+
"linux tar.gz": {os: "linux", arch: "amd64", format: "targz", expected: "linux-x86_64.tar.gz", err: nil},
25+
"linux pkg.tar.zst": {os: "linux", arch: "amd64", format: "pkg.tar.zst", expected: "", err: ErrUnsupportedPlatform},
26+
"darwin arm64": {os: "darwin", arch: "arm64", format: "targz", expected: "darwin-aarch64.tar.gz", err: nil},
27+
}
28+
for name, tc := range tests {
29+
t.Run(name, func(t *gtesting.T) {
30+
got, err := GetPackageSuffix(tc.os, tc.arch, tc.format)
31+
if !errors.Is(err, tc.err) {
32+
t.Fatalf("wrong error. expected: %v got: %v", tc.err, err)
33+
}
34+
if got != tc.expected {
35+
t.Fatalf("wrong output. expected: %s got: %s", tc.expected, got)
36+
}
37+
})
38+
}
39+
}

pkg/testing/fetcher.go

+19-9
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,23 @@ var (
3131
// packageArchMap provides a mapping for the endings of the builds of Elastic Agent based on the
3232
// operating system and architecture.
3333
var packageArchMap = map[string]string{
34-
"linux-amd64": "linux-x86_64.tar.gz",
35-
"linux-arm64": "linux-arm64.tar.gz",
36-
"windows-amd64": "windows-x86_64.zip",
37-
"darwin-amd64": "darwin-x86_64.tar.gz",
38-
"darwin-arm64": "darwin-aarch64.tar.gz",
34+
"linux-amd64-targz": "linux-x86_64.tar.gz",
35+
"linux-amd64-deb": "amd64.deb",
36+
"linux-amd64-rpm": "x86_64.rpm",
37+
"linux-arm64-targz": "linux-arm64.tar.gz",
38+
"linux-arm64-deb": "arm64.deb",
39+
"linux-arm64-rpm": "aarch64.rpm",
40+
"windows-amd64-zip": "windows-x86_64.zip",
41+
"darwin-amd64-targz": "darwin-x86_64.tar.gz",
42+
"darwin-arm64-targz": "darwin-aarch64.tar.gz",
3943
}
4044

4145
// GetPackageSuffix returns the suffix ending for the builds of Elastic Agent based on the
4246
// operating system and architecture.
43-
func GetPackageSuffix(operatingSystem string, architecture string) (string, error) {
44-
suffix, ok := packageArchMap[fmt.Sprintf("%s-%s", operatingSystem, architecture)]
47+
func GetPackageSuffix(operatingSystem string, architecture string, packageFormat string) (string, error) {
48+
suffix, ok := packageArchMap[fmt.Sprintf("%s-%s-%s", operatingSystem, architecture, packageFormat)]
4549
if !ok {
46-
return "", fmt.Errorf("%w: %s/%s", ErrUnsupportedPlatform, operatingSystem, architecture)
50+
return "", fmt.Errorf("%w: %s/%s/%s", ErrUnsupportedPlatform, operatingSystem, architecture, packageFormat)
4751
}
4852
return suffix, nil
4953
}
@@ -68,7 +72,7 @@ type Fetcher interface {
6872
//
6973
// The extraction is handled by the caller. This should only download the file
7074
// and place it into the directory.
71-
Fetch(ctx context.Context, operatingSystem string, architecture string, version string) (FetcherResult, error)
75+
Fetch(ctx context.Context, operatingSystem string, architecture string, version string, packageFormat string) (FetcherResult, error)
7276
}
7377

7478
// fetchCache is global to all tests, reducing the time required to fetch the needed artifacts
@@ -105,6 +109,12 @@ func splitFileType(name string) (string, string, error) {
105109
if strings.HasSuffix(name, ".zip") {
106110
return strings.TrimSuffix(name, ".zip"), ".zip", nil
107111
}
112+
if strings.HasSuffix(name, ".deb") {
113+
return strings.TrimSuffix(name, ".deb"), ".deb", nil
114+
}
115+
if strings.HasSuffix(name, ".rpm") {
116+
return strings.TrimSuffix(name, ".rpm"), ".rpm", nil
117+
}
108118
return "", "", fmt.Errorf("unknown file extension type: %s", filepath.Ext(name))
109119
}
110120

pkg/testing/fetcher_artifact.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ func (f *artifactFetcher) Name() string {
5959
}
6060

6161
// Fetch fetches the Elastic Agent and places the resulting binary at the path.
62-
func (f *artifactFetcher) Fetch(ctx context.Context, operatingSystem string, architecture string, version string) (FetcherResult, error) {
63-
suffix, err := GetPackageSuffix(operatingSystem, architecture)
62+
func (f *artifactFetcher) Fetch(ctx context.Context, operatingSystem string, architecture string, version string, packageFormat string) (FetcherResult, error) {
63+
suffix, err := GetPackageSuffix(operatingSystem, architecture, packageFormat)
6464
if err != nil {
6565
return nil, err
6666
}

pkg/testing/fetcher_artifact_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func TestArtifactFetcher_Default(t *testing.T) {
2929
af.doer = newFakeHttpClient(t)
3030

3131
tmp := t.TempDir()
32-
res, err := f.Fetch(context.Background(), "linux", "amd64", "8.12.0")
32+
res, err := f.Fetch(context.Background(), "linux", "amd64", "8.12.0", "targz")
3333
require.NoError(t, err)
3434

3535
err = res.Fetch(context.Background(), t, tmp)
@@ -46,7 +46,7 @@ func TestArtifactFetcher_Snapshot(t *testing.T) {
4646
af.doer = newFakeHttpClient(t)
4747

4848
tmp := t.TempDir()
49-
res, err := f.Fetch(context.Background(), "linux", "amd64", "8.13.0-SNAPSHOT")
49+
res, err := f.Fetch(context.Background(), "linux", "amd64", "8.13.0-SNAPSHOT", "targz")
5050
require.NoError(t, err)
5151

5252
err = res.Fetch(context.Background(), t, tmp)
@@ -64,7 +64,7 @@ func TestArtifactFetcher_SnapshotOnly(t *testing.T) {
6464
af.doer = newFakeHttpClient(t)
6565

6666
tmp := t.TempDir()
67-
res, err := f.Fetch(context.Background(), "linux", "amd64", "8.13.0")
67+
res, err := f.Fetch(context.Background(), "linux", "amd64", "8.13.0", "targz")
6868
require.NoError(t, err)
6969

7070
err = res.Fetch(context.Background(), t, tmp)
@@ -82,7 +82,7 @@ func TestArtifactFetcher_Build(t *testing.T) {
8282
af.doer = newFakeHttpClient(t)
8383

8484
tmp := t.TempDir()
85-
res, err := f.Fetch(context.Background(), "linux", "amd64", "8.13.0-SNAPSHOT+l5snflwr")
85+
res, err := f.Fetch(context.Background(), "linux", "amd64", "8.13.0-SNAPSHOT+l5snflwr", "targz")
8686
require.NoError(t, err)
8787

8888
err = res.Fetch(context.Background(), t, tmp)

pkg/testing/fetcher_http.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ func (h HttpFetcher) Name() string {
4545
return fmt.Sprintf("httpFetcher-%s", sanitizeFetcherName(h.baseURL))
4646
}
4747

48-
func (h HttpFetcher) Fetch(ctx context.Context, operatingSystem string, architecture string, version string) (FetcherResult, error) {
49-
suffix, err := GetPackageSuffix(operatingSystem, architecture)
48+
func (h HttpFetcher) Fetch(ctx context.Context, operatingSystem string, architecture string, version string, packageFormat string) (FetcherResult, error) {
49+
suffix, err := GetPackageSuffix(operatingSystem, architecture, packageFormat)
5050
if err != nil {
5151
return nil, err
5252
}

pkg/testing/fetcher_http_test.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ func TestHttpFetcher_Fetch(t *testing.T) {
2424
operatingSystem string
2525
architecture string
2626
version string
27+
pkgFormat string
2728
}
2829
tests := []struct {
2930
name string
@@ -38,6 +39,7 @@ func TestHttpFetcher_Fetch(t *testing.T) {
3839
operatingSystem: "linux",
3940
architecture: "arm64",
4041
version: "1.2.3",
42+
pkgFormat: "targz",
4143
},
4244
want: &httpFetcherResult{
4345
baseURL: "https://artifacts.elastic.co/downloads/beats/elastic-agent/",
@@ -52,6 +54,7 @@ func TestHttpFetcher_Fetch(t *testing.T) {
5254
operatingSystem: "windows",
5355
architecture: "amd64",
5456
version: "1.2.3",
57+
pkgFormat: "zip",
5558
},
5659
want: &httpFetcherResult{
5760
baseURL: "http://somehost.somedomain/some/path/here",
@@ -69,7 +72,7 @@ func TestHttpFetcher_Fetch(t *testing.T) {
6972
h := NewHttpFetcher(opts...)
7073
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
7174
defer cancel()
72-
got, err := h.Fetch(ctx, tt.args.operatingSystem, tt.args.architecture, tt.args.version)
75+
got, err := h.Fetch(ctx, tt.args.operatingSystem, tt.args.architecture, tt.args.version, tt.args.pkgFormat)
7376
if !tt.wantErr(t, err, fmt.Sprintf("Fetch(%v, %v, %v, %v)", ctx, tt.args.operatingSystem, tt.args.architecture, tt.args.version)) {
7477
return
7578
}

pkg/testing/fetcher_local.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ func (f *localFetcher) Name() string {
5555
}
5656

5757
// Fetch fetches the Elastic Agent and places the resulting binary at the path.
58-
func (f *localFetcher) Fetch(_ context.Context, operatingSystem string, architecture string, version string) (FetcherResult, error) {
59-
suffix, err := GetPackageSuffix(operatingSystem, architecture)
58+
func (f *localFetcher) Fetch(_ context.Context, operatingSystem string, architecture string, version string, packageFormat string) (FetcherResult, error) {
59+
suffix, err := GetPackageSuffix(operatingSystem, architecture, packageFormat)
6060
if err != nil {
6161
return nil, err
6262
}

pkg/testing/fetcher_local_test.go

+10-2
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,13 @@ func TestLocalFetcher(t *testing.T) {
2828
snapshotContentHash := []byte("snapshot contents hash")
2929
noSnapshotContent := []byte("not snapshot contents")
3030
noSnapshotContentHash := []byte("not snapshot contents hash")
31+
pkgFormat := "targz"
32+
if runtime.GOOS == "windows" {
33+
pkgFormat = "zip"
34+
}
3135

3236
testdata := t.TempDir()
33-
suffix, err := GetPackageSuffix(runtime.GOOS, runtime.GOARCH)
37+
suffix, err := GetPackageSuffix(runtime.GOOS, runtime.GOARCH, pkgFormat)
3438
require.NoError(t, err)
3539

3640
snapshotPath := fmt.Sprintf("elastic-agent-%s-SNAPSHOT-%s", baseVersion, suffix)
@@ -92,8 +96,12 @@ func TestLocalFetcher(t *testing.T) {
9296
tmp := t.TempDir()
9397

9498
f := LocalFetcher(testdata, tc.opts...)
99+
pkgFormat := "targz"
100+
if runtime.GOOS == "windows" {
101+
pkgFormat = "zip"
102+
}
95103
got, err := f.Fetch(
96-
context.Background(), runtime.GOOS, runtime.GOARCH, tc.version)
104+
context.Background(), runtime.GOOS, runtime.GOARCH, tc.version, pkgFormat)
97105
require.NoError(t, err)
98106

99107
err = got.Fetch(context.Background(), t, tmp)

pkg/testing/fixture.go

+28-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type Fixture struct {
4141
fetcher Fetcher
4242
operatingSystem string
4343
architecture string
44+
packageFormat string
4445
logOutput bool
4546
allowErrs bool
4647
connectTimout time.Duration
@@ -83,6 +84,14 @@ func WithOSArchitecture(operatingSystem string, architecture string) FixtureOpt
8384
}
8485
}
8586

87+
// WithPackageFormat changes the package format to use for the fixture.
88+
// By default, targz is picked except for windows which uses zip
89+
func WithPackageFormat(packageFormat string) FixtureOpt {
90+
return func(f *Fixture) {
91+
f.packageFormat = packageFormat
92+
}
93+
}
94+
8695
// WithLogOutput instructs the fixture to log all Elastic Agent output to the test log.
8796
// By default, the Elastic Agent output will not be logged to the test logger.
8897
func WithLogOutput() FixtureOpt {
@@ -139,13 +148,18 @@ func NewFixture(t *testing.T, version string, opts ...FixtureOpt) (*Fixture, err
139148
if !ok {
140149
return nil, errors.New("unable to determine callers file path")
141150
}
151+
pkgFormat := "targz"
152+
if runtime.GOOS == "windows" {
153+
pkgFormat = "zip"
154+
}
142155
f := &Fixture{
143156
t: t,
144157
version: version,
145158
caller: caller,
146159
fetcher: ArtifactFetcher(),
147160
operatingSystem: runtime.GOOS,
148161
architecture: runtime.GOARCH,
162+
packageFormat: pkgFormat,
149163
connectTimout: 15 * time.Second,
150164
// default to elastic-agent, can be changed by a set FixtureOpt below
151165
binaryName: "elastic-agent",
@@ -253,6 +267,11 @@ func (f *Fixture) SrcPackage(ctx context.Context) (string, error) {
253267
return f.srcPackage, nil
254268
}
255269

270+
// PackageFormat returns the package format for the fixture
271+
func (f *Fixture) PackageFormat() string {
272+
return f.packageFormat
273+
}
274+
256275
func ExtractArtifact(l Logger, artifactFile, outputDir string) error {
257276
filename := filepath.Base(artifactFile)
258277
_, ext, err := splitFileType(filename)
@@ -271,6 +290,11 @@ func ExtractArtifact(l Logger, artifactFile, outputDir string) error {
271290
if err != nil {
272291
return fmt.Errorf("failed to unzip %s: %w", artifactFile, err)
273292
}
293+
case ".deb", "rpm":
294+
err := copy.Copy(artifactFile, filepath.Join(outputDir, filepath.Base(artifactFile)))
295+
if err != nil {
296+
return fmt.Errorf("failed to copy %s to %s: %w", artifactFile, outputDir, err)
297+
}
274298
}
275299
l.Logf("Completed extraction of artifact %s to %s", filename, outputDir)
276300
return nil
@@ -813,6 +837,9 @@ func (f *Fixture) binaryPath() string {
813837
workDir = filepath.Join(paths.DefaultBasePath, "Elastic", "Agent")
814838
}
815839
}
840+
if f.packageFormat == "deb" {
841+
workDir = "/usr/bin"
842+
}
816843
defaultBin := "elastic-agent"
817844
if f.binaryName != "" {
818845
defaultBin = f.binaryName
@@ -840,7 +867,7 @@ func (f *Fixture) fetch(ctx context.Context) (string, error) {
840867
cache.dir = dir
841868
}
842869

843-
res, err := f.fetcher.Fetch(ctx, f.operatingSystem, f.architecture, f.version)
870+
res, err := f.fetcher.Fetch(ctx, f.operatingSystem, f.architecture, f.version, f.packageFormat)
844871
if err != nil {
845872
return "", err
846873
}

0 commit comments

Comments
 (0)