argo-cd/cmpserver/plugin/plugin_test.go
Michael Crenshaw ab1b0ec4ac
test: fix plugin var test for OSX (#9590)
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-08 10:56:23 -04:00

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)
}