mirror of https://github.com/knative/func.git
test: add e2e test for config volumes (#612)
This commit is contained in:
parent
e1f164d2ca
commit
d1b322fe82
|
@ -0,0 +1,164 @@
|
||||||
|
//go:build e2e
|
||||||
|
// +build e2e
|
||||||
|
|
||||||
|
package e2e
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/client-go/kubernetes"
|
||||||
|
"knative.dev/kn-plugin-func/k8s"
|
||||||
|
)
|
||||||
|
|
||||||
|
// setupConfigVolumesTest add to cluster config maps and secrets that will be used as volumes
|
||||||
|
// during tests
|
||||||
|
func setupConfigVolumesTest(t *testing.T) {
|
||||||
|
|
||||||
|
config, err := k8s.GetClientConfig().ClientConfig()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
clientset, err := kubernetes.NewForConfig(config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
namespace, _, _ := k8s.GetClientConfig().Namespace()
|
||||||
|
|
||||||
|
// Add Config Map
|
||||||
|
configMap := corev1.ConfigMap{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "test-cm-volume"},
|
||||||
|
Data: map[string]string{
|
||||||
|
"config-key1": "Hi",
|
||||||
|
"config-key2": "Hello",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_, err = clientset.CoreV1().ConfigMaps(namespace).Create(context.Background(), &configMap, metav1.CreateOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add Secret
|
||||||
|
secret := &corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "test-secret-volume"},
|
||||||
|
Data: map[string][]byte{
|
||||||
|
"secret-key1": []byte("pw1"),
|
||||||
|
"secret-key2": []byte("pw2"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_, err = clientset.CoreV1().Secrets(namespace).Create(context.Background(), secret, metav1.CreateOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// tearDownConfigVolumesTest removes cluster config maps and secrets used by the test
|
||||||
|
func tearDownConfigVolumesTest() {
|
||||||
|
|
||||||
|
config, _ := k8s.GetClientConfig().ClientConfig()
|
||||||
|
clientset, _ := kubernetes.NewForConfig(config)
|
||||||
|
namespace, _, _ := k8s.GetClientConfig().Namespace()
|
||||||
|
|
||||||
|
_ = clientset.CoreV1().ConfigMaps(namespace).Delete(context.Background(), "test-cm-volume", metav1.DeleteOptions{})
|
||||||
|
_ = clientset.CoreV1().Secrets(namespace).Delete(context.Background(), "test-secret-volume", metav1.DeleteOptions{})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigVolumesAdd generates a go function to test `func config volumes add` with user input
|
||||||
|
func ConfigVolumesAdd(knFunc *TestShellInteractiveCmdRunner, project *FunctionTestProject) func(userInput ...string) {
|
||||||
|
return PrepareInteractiveCommand(knFunc, "config", "volumes", "add", "--path", project.ProjectPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigVolumesRemove generates a go function to test `func config volumes remove` with user input
|
||||||
|
func ConfigVolumesRemove(knFunc *TestShellInteractiveCmdRunner, project *FunctionTestProject) func(userInput ...string) {
|
||||||
|
return PrepareInteractiveCommand(knFunc, "config", "volumes", "remove", "--path", project.ProjectPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestConfigVolumes verifies configMaps and secrets were properly mounted as volumes and accessible to the function
|
||||||
|
// Test consist reproduce the user experience to add volumes (both config and secrets) and deploy a function that
|
||||||
|
// makes use of the data/
|
||||||
|
// It setup "configMaps" and "secrets" on the cluster. A custom kn Function template (from a remote repository)
|
||||||
|
// is used to validate the data can be accessed from the deployed function perspective.
|
||||||
|
func TestConfigVolumes(t *testing.T) {
|
||||||
|
|
||||||
|
setupConfigVolumesTest(t)
|
||||||
|
defer tearDownConfigVolumesTest()
|
||||||
|
|
||||||
|
knFunc := NewTestShellInteractiveCmdRunner(t)
|
||||||
|
knFunc.TestShell.ShouldDumpOnSuccess = false
|
||||||
|
knFunc.commandSleepInterval = time.Millisecond * 1500
|
||||||
|
|
||||||
|
// On When...
|
||||||
|
project := FunctionTestProject{}
|
||||||
|
project.Runtime = "go"
|
||||||
|
project.Template = "volumes"
|
||||||
|
project.FunctionName = "test-config-volumes"
|
||||||
|
project.ProjectPath = filepath.Join(os.TempDir(), project.FunctionName)
|
||||||
|
project.RemoteRepository = "http://github.com/boson-project/test-templates.git"
|
||||||
|
|
||||||
|
Create(t, knFunc.TestShell, project)
|
||||||
|
defer project.RemoveProjectFolder()
|
||||||
|
|
||||||
|
/*
|
||||||
|
? What do you want to mount as a Volume? [Use arrows to move, type to filter]
|
||||||
|
> ConfigMap
|
||||||
|
Secret
|
||||||
|
*/
|
||||||
|
configVolumesAdd := ConfigVolumesAdd(knFunc, &project)
|
||||||
|
|
||||||
|
configVolumesAdd(
|
||||||
|
enter, // > ConfigMap
|
||||||
|
"test-cm-volume", enter, // Which "ConfigMap" do you want to mount?
|
||||||
|
"/test/cm-volume", enter) // Please specify the path where the ConfigMap should be mounted:
|
||||||
|
|
||||||
|
configVolumesAdd(
|
||||||
|
arrowDown, enter, // > Secret
|
||||||
|
"test-secret-volume", enter, // Which "Secret" do you want to mount?
|
||||||
|
"/test/secret-volume", enter) // Please specify the path where the Secret should be mounted:
|
||||||
|
|
||||||
|
// Adding unwanted volume entries (to simulate user mistakes)
|
||||||
|
configVolumesAdd(
|
||||||
|
enter,
|
||||||
|
"test-cm-volume", enter,
|
||||||
|
"/test/bad-cm", enter)
|
||||||
|
|
||||||
|
configVolumesAdd(
|
||||||
|
arrowDown, enter,
|
||||||
|
"test-secret-volume", enter,
|
||||||
|
"/test/bad-secret", enter)
|
||||||
|
|
||||||
|
// Delete unwanted entries
|
||||||
|
configVolumesRemove := ConfigVolumesRemove(knFunc, &project)
|
||||||
|
configVolumesRemove("/bad-secret", enter)
|
||||||
|
configVolumesRemove("/bad-cm", enter)
|
||||||
|
|
||||||
|
// Deploy
|
||||||
|
Deploy(t, knFunc.TestShell, &project)
|
||||||
|
defer Delete(t, knFunc.TestShell, &project)
|
||||||
|
ReadyCheck(t, knFunc.TestShell, project)
|
||||||
|
|
||||||
|
// Validate
|
||||||
|
// The function template used by this test will return
|
||||||
|
// file content for the file specified as a query parameter named 'v'
|
||||||
|
expectedMap := map[string]string{
|
||||||
|
"/test/cm-volume/config-key1": "Hi",
|
||||||
|
"/test/cm-volume/config-key2": "Hello",
|
||||||
|
"/test/secret-volume/secret-key1": "pw1",
|
||||||
|
"/test/secret-volume/secret-key2": "pw2",
|
||||||
|
"/test/bad-cm/config-key1": "",
|
||||||
|
"/test/bad-secret/secret-key1": "",
|
||||||
|
}
|
||||||
|
functionRespValidator := FunctionHttpResponsivenessValidator{runtime: "go"}
|
||||||
|
for expectedVolumeEntry, expectedFileContent := range expectedMap {
|
||||||
|
functionRespValidator.targetUrl = "%v?v=" + expectedVolumeEntry
|
||||||
|
functionRespValidator.expects = expectedFileContent
|
||||||
|
functionRespValidator.Validate(t, project)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue