mirror of
https://github.com/argoproj/argo-cd
synced 2026-04-21 17:07:16 +00:00
268 lines
6.2 KiB
Go
268 lines
6.2 KiB
Go
package plugin
|
|
|
|
import (
|
|
"context"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
|
|
"github.com/argoproj/argo-cd/v2/cmpserver/apiclient"
|
|
"github.com/argoproj/argo-cd/v2/test"
|
|
)
|
|
|
|
func newService(configFilePath string) (*Service, error) {
|
|
config, err := ReadPluginConfig(configFilePath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
initConstants := CMPServerInitConstants{
|
|
PluginConfig: *config,
|
|
}
|
|
|
|
service := &Service{
|
|
initConstants: initConstants,
|
|
}
|
|
return service, nil
|
|
}
|
|
|
|
type pluginOpt func(*CMPServerInitConstants)
|
|
|
|
func withDiscover(d Discover) pluginOpt {
|
|
return func(cic *CMPServerInitConstants) {
|
|
cic.PluginConfig.Spec.Discover = d
|
|
}
|
|
}
|
|
|
|
func buildPluginConfig(opts ...pluginOpt) *CMPServerInitConstants {
|
|
cic := &CMPServerInitConstants{
|
|
PluginConfig: PluginConfig{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "ConfigManagementPlugin",
|
|
APIVersion: "argoproj.io/v1alpha1",
|
|
},
|
|
Metadata: metav1.ObjectMeta{
|
|
Name: "some-plugin",
|
|
},
|
|
Spec: PluginConfigSpec{
|
|
Version: "v1.0",
|
|
},
|
|
},
|
|
}
|
|
for _, opt := range opts {
|
|
opt(cic)
|
|
}
|
|
return cic
|
|
}
|
|
|
|
func TestMatchRepository(t *testing.T) {
|
|
type fixture struct {
|
|
service *Service
|
|
path string
|
|
env []*apiclient.EnvEntry
|
|
}
|
|
setup := func(t *testing.T, opts ...pluginOpt) *fixture {
|
|
t.Helper()
|
|
cic := buildPluginConfig(opts...)
|
|
path := filepath.Join(test.GetTestDir(t), "testdata", "kustomize")
|
|
s := NewService(*cic)
|
|
return &fixture{
|
|
service: s,
|
|
path: path,
|
|
env: []*apiclient.EnvEntry{{Name: "ENV_VAR", Value: "1"}},
|
|
}
|
|
}
|
|
t.Run("will match plugin by filename", func(t *testing.T) {
|
|
// given
|
|
d := Discover{
|
|
FileName: "kustomization.yaml",
|
|
}
|
|
f := setup(t, withDiscover(d))
|
|
|
|
// when
|
|
match, err := f.service.matchRepository(context.Background(), f.path, f.env)
|
|
|
|
// then
|
|
assert.NoError(t, err)
|
|
assert.True(t, match)
|
|
})
|
|
t.Run("will not match plugin by filename if file not found", func(t *testing.T) {
|
|
// given
|
|
d := Discover{
|
|
FileName: "not_found.yaml",
|
|
}
|
|
f := setup(t, withDiscover(d))
|
|
|
|
// when
|
|
match, err := f.service.matchRepository(context.Background(), f.path, f.env)
|
|
|
|
// then
|
|
assert.NoError(t, err)
|
|
assert.False(t, match)
|
|
})
|
|
t.Run("will match plugin by glob", func(t *testing.T) {
|
|
// given
|
|
d := Discover{
|
|
Find: Find{
|
|
Glob: "**/*/plugin.yaml",
|
|
},
|
|
}
|
|
f := setup(t, withDiscover(d))
|
|
|
|
// when
|
|
match, err := f.service.matchRepository(context.Background(), f.path, f.env)
|
|
|
|
// then
|
|
assert.NoError(t, err)
|
|
assert.True(t, match)
|
|
})
|
|
t.Run("will not match plugin by glob if not found", func(t *testing.T) {
|
|
// given
|
|
d := Discover{
|
|
Find: Find{
|
|
Glob: "**/*/not_found.yaml",
|
|
},
|
|
}
|
|
f := setup(t, withDiscover(d))
|
|
|
|
// when
|
|
match, err := f.service.matchRepository(context.Background(), f.path, f.env)
|
|
|
|
// then
|
|
assert.NoError(t, err)
|
|
assert.False(t, match)
|
|
})
|
|
t.Run("will match plugin by command when returns any output", func(t *testing.T) {
|
|
// given
|
|
d := Discover{
|
|
Find: Find{
|
|
Command: Command{
|
|
Command: []string{"echo", "test"},
|
|
},
|
|
},
|
|
}
|
|
f := setup(t, withDiscover(d))
|
|
|
|
// when
|
|
match, err := f.service.matchRepository(context.Background(), f.path, f.env)
|
|
|
|
// then
|
|
assert.NoError(t, err)
|
|
assert.True(t, match)
|
|
})
|
|
t.Run("will not match plugin by command when returns no output", func(t *testing.T) {
|
|
// given
|
|
d := Discover{
|
|
Find: Find{
|
|
Command: Command{
|
|
Command: []string{"echo"},
|
|
},
|
|
},
|
|
}
|
|
f := setup(t, withDiscover(d))
|
|
|
|
// when
|
|
match, err := f.service.matchRepository(context.Background(), f.path, f.env)
|
|
|
|
// then
|
|
assert.NoError(t, err)
|
|
assert.False(t, match)
|
|
})
|
|
t.Run("will match plugin because env var defined", func(t *testing.T) {
|
|
// given
|
|
d := Discover{
|
|
Find: Find{
|
|
Command: Command{
|
|
Command: []string{"sh", "-c", "echo -n $ENV_VAR"},
|
|
},
|
|
},
|
|
}
|
|
f := setup(t, withDiscover(d))
|
|
|
|
// when
|
|
match, err := f.service.matchRepository(context.Background(), f.path, f.env)
|
|
|
|
// then
|
|
assert.NoError(t, err)
|
|
assert.True(t, match)
|
|
})
|
|
t.Run("will not match plugin because no env var defined", func(t *testing.T) {
|
|
// given
|
|
d := Discover{
|
|
Find: Find{
|
|
Command: Command{
|
|
// Use printf instead of echo since OSX prints the "-n" when there's no additional arg.
|
|
Command: []string{"sh", "-c", `printf "%s" "$ENV_NO_VAR"`},
|
|
},
|
|
},
|
|
}
|
|
f := setup(t, withDiscover(d))
|
|
|
|
// when
|
|
match, err := f.service.matchRepository(context.Background(), f.path, f.env)
|
|
|
|
// then
|
|
assert.NoError(t, err)
|
|
assert.False(t, match)
|
|
})
|
|
t.Run("will not match plugin by command when command fails", func(t *testing.T) {
|
|
// given
|
|
d := Discover{
|
|
Find: Find{
|
|
Command: Command{
|
|
Command: []string{"cat", "nil"},
|
|
},
|
|
},
|
|
}
|
|
f := setup(t, withDiscover(d))
|
|
|
|
// when
|
|
match, err := f.service.matchRepository(context.Background(), f.path, f.env)
|
|
|
|
// then
|
|
assert.Error(t, err)
|
|
assert.False(t, match)
|
|
})
|
|
}
|
|
|
|
func Test_Negative_ConfigFile_DoesnotExist(t *testing.T) {
|
|
configFilePath := "./testdata/kustomize-neg/config"
|
|
service, err := newService(configFilePath)
|
|
require.Error(t, err)
|
|
require.Nil(t, service)
|
|
}
|
|
|
|
func TestGenerateManifest(t *testing.T) {
|
|
configFilePath := "./testdata/kustomize/config"
|
|
service, err := newService(configFilePath)
|
|
require.NoError(t, err)
|
|
|
|
res1, err := service.generateManifest(context.Background(), "", nil)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, res1)
|
|
|
|
expectedOutput := "{\"apiVersion\":\"v1\",\"data\":{\"foo\":\"bar\"},\"kind\":\"ConfigMap\",\"metadata\":{\"name\":\"my-map\"}}"
|
|
if res1 != nil {
|
|
require.Equal(t, expectedOutput, res1.Manifests[0])
|
|
}
|
|
}
|
|
|
|
// TestRunCommandContextTimeout makes sure the command dies at timeout rather than sleeping past the timeout.
|
|
func TestRunCommandContextTimeout(t *testing.T) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 990*time.Millisecond)
|
|
defer cancel()
|
|
// Use a subshell so there's a child command.
|
|
command := Command{
|
|
Command: []string{"sh", "-c"},
|
|
Args: []string{"sleep 5"},
|
|
}
|
|
before := time.Now()
|
|
_, err := runCommand(ctx, command, "", []string{})
|
|
after := time.Now()
|
|
assert.Error(t, err) // The command should time out, causing an error.
|
|
assert.Less(t, after.Sub(before), 1*time.Second)
|
|
}
|