forked from elastic/elastic-agent
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathupgrade_integration_test.go
166 lines (134 loc) · 5.39 KB
/
upgrade_integration_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
//go:build integration
package upgrade
import (
"context"
"flag"
"fmt"
"os"
"path/filepath"
"strconv"
"testing"
"github.com/elastic/elastic-agent-libs/logp"
"github.com/elastic/elastic-agent/internal/pkg/agent/application/coordinator"
"github.com/elastic/elastic-agent/internal/pkg/agent/application/info"
"github.com/elastic/elastic-agent/internal/pkg/agent/application/paths"
"github.com/elastic/elastic-agent/internal/pkg/agent/application/reexec"
"github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/artifact"
"github.com/elastic/elastic-agent/internal/pkg/fleetapi"
"github.com/elastic/elastic-agent/pkg/component"
)
type mockAction struct {
version string
sourceURI string
fleetAction *fleetapi.ActionUpgrade
}
func (m mockAction) Version() string {
return m.version
}
func (m mockAction) SourceURI() string {
return m.sourceURI
}
func (m mockAction) FleetAction() *fleetapi.ActionUpgrade {
return m.fleetAction
}
type nopReExec struct{}
func (m nopReExec) ReExec(shutdownCallback reexec.ShutdownCallbackFn, argOverrides ...string) {}
type nopAcker struct{}
func (n nopAcker) Ack(ctx context.Context, action fleetapi.Action) error { return nil }
func (n nopAcker) Commit(ctx context.Context) error { return nil }
const mockAgentScriptTpl = `#!/bin/sh
echo "reexec-called" >> %s
exit 0
`
// SetupPathsForTesting creates all folders/files necessary for the integration
// tests on this file. It also sets some global values using the `paths` package.
//
// The returned values are:
// - The temporary directory
// - The reexec log file.
func setupPathsForTesing(t *testing.T) (string, string) {
t.Helper()
targetDirectory := t.TempDir()
paths.SetDownloads(targetDirectory)
paths.SetInstall(targetDirectory)
paths.SetTop(targetDirectory)
paths.SetVersionHome(true)
if err := os.MkdirAll(paths.Home(), 0o755); err != nil {
t.Fatalf("cannot create elastic-agent home path '%s': %s", paths.Home(), err)
}
mockAgent := filepath.Join(paths.Home(), "elastic-agent")
agentFile, err := os.OpenFile(mockAgent, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o755)
if err != nil {
t.Fatalf("cannot create 'elastic-agent binary' file: %s", err)
}
reexecLogFile := filepath.Join(targetDirectory, "reexec-called")
mockAgentScript := fmt.Sprintf(mockAgentScriptTpl, reexecLogFile)
if _, err := agentFile.WriteString(mockAgentScript); err != nil {
t.Fatal(err)
}
if err := agentFile.Close(); err != nil {
t.Fatalf("cannot close elastic-agent-script': %s", err)
}
t.Logf("Paths: Download: %s, Install: %s, Home: %s", paths.Downloads(), paths.Install(), paths.Home())
return targetDirectory, reexecLogFile
}
// setLogLevel configures logp in development mode if -test.v is true
//
// This helps a lot to debug failing tests
func setLogLevel(t *testing.T) {
t.Helper()
if !flag.Parsed() {
t.Fatal("not parsed")
}
f := flag.CommandLine.Lookup("test.v")
if f == nil {
t.Fatal("test flag not set")
}
strVal := f.Value.String()
verbose, err := strconv.ParseBool(strVal)
if err != nil {
// This should never happen because the testing package already ensures
// that test.v is a valid boolean.
t.Logf("cannot parse test.v='%s' as boolean, disabling logging.", strVal)
}
if verbose {
logp.DevelopmentSetup()
t.Log("logp level set as DevelopmentSetup")
}
}
// TestUpgrade unit-tests upgrader.TestUpgrade
// go test -v -tags=integration -run=Upgrade -ldflags="-X github.com/elastic/elastic-agent/internal/pkg/release.allowEmptyPgp=true -X github.com/elastic/elastic-agent/internal/pkg/release.allowUpgrade=true"
// dlv test --build-flags="-ldflags='-X github.com/elastic/elastic-agent/internal/pkg/release.allowEmptyPgp=true -X github.com/elastic/elastic-agent/internal/pkg/release.allowUpgrade=true' -tags=integration" . -- -test.run=Upgrade
func TestUpgrade(t *testing.T) {
setLogLevel(t)
setupPathsForTesing(t)
agentInfo := &info.AgentInfo{}
upgrader := NewUpgrader(logp.L(), artifact.DefaultConfig(), agentInfo)
callback, err := upgrader.Upgrade(context.Background(), "8.7.0", "file:///home/tiago/sandbox/dropPath", nil)
if err != nil {
t.Fatalf("could not execute upgrade: %s", err)
}
if callback != nil {
if err := callback(); err != nil {
t.Fatalf("error calling callback: %s", err)
}
}
}
// TestCoordinator unit-tests cordinator.Upgrade
// go test -v -tags=integration -run=Coordinator -ldflags="-X github.com/elastic/elastic-agent/internal/pkg/release.allowEmptyPgp=true -X github.com/elastic/elastic-agent/internal/pkg/release.allowUpgrade=true"
// dlv test --build-flags="-ldflags='-X github.com/elastic/elastic-agent/internal/pkg/release.allowEmptyPgp=true -X github.com/elastic/elastic-agent/internal/pkg/release.allowUpgrade=true' -tags=integration" . -- -test.run=Coordinator
func TestCoordinator(t *testing.T) {
setLogLevel(t)
_, reexecLogFile := setupPathsForTesing(t)
agentInfo := &info.AgentInfo{}
upgrader := NewUpgrader(logp.L(), artifact.DefaultConfig(), agentInfo)
coord := coordinator.New(logp.L(), agentInfo, component.RuntimeSpecs{}, nopReExec{}, upgrader, nil, nil, nil, nil, nil)
err := coord.Upgrade(context.Background(), "8.7.0", "file:///home/tiago/sandbox/dropPath", nil)
if err != nil {
t.Fatalf("could not execute upgrade: %s", err)
}
if _, err := os.Stat(reexecLogFile); err != nil {
t.Fatalf("re-exec log file does not exisit, this usually means the"+
" reexec operation/callback did not run successfully: %s", err.Error())
}
}