mirror of https://github.com/dapr/cli.git
adding e2e test for multi app run k8s (#1336)
Signed-off-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>
This commit is contained in:
parent
a15a3eb856
commit
41f324016e
7
Makefile
7
Makefile
|
|
@ -155,6 +155,13 @@ test: test-deps
|
||||||
test-e2e-k8s: test-deps
|
test-e2e-k8s: test-deps
|
||||||
gotestsum --jsonfile $(TEST_OUTPUT_FILE) --format standard-verbose -- -timeout 20m -count=1 -tags=e2e ./tests/e2e/kubernetes/...
|
gotestsum --jsonfile $(TEST_OUTPUT_FILE) --format standard-verbose -- -timeout 20m -count=1 -tags=e2e ./tests/e2e/kubernetes/...
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# E2E Tests for K8s Template exec #
|
||||||
|
################################################################################
|
||||||
|
.PHONY: test-e2e-k8s-template
|
||||||
|
test-e2e-k8s-template: test-deps
|
||||||
|
gotestsum --jsonfile $(TEST_OUTPUT_FILE) --format standard-verbose -- -timeout 20m -count=1 -tags=templatek8s ./tests/e2e/kubernetes/...
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Build, E2E Tests for Kubernetes #
|
# Build, E2E Tests for Kubernetes #
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,6 @@ func streamContainerLogsToDisk(ctx context.Context, appID string, appLogWriter,
|
||||||
func getPods(ctx context.Context, appID string, podClient v1.PodInterface) (*corev1.PodList, error) {
|
func getPods(ctx context.Context, appID string, podClient v1.PodInterface) (*corev1.PodList, error) {
|
||||||
listCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
listCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||||
labelSelector := fmt.Sprintf("%s=%s", daprAppIDKey, appID)
|
labelSelector := fmt.Sprintf("%s=%s", daprAppIDKey, appID)
|
||||||
fmt.Println("Select", labelSelector)
|
|
||||||
podList, err := podClient.List(listCtx, metav1.ListOptions{
|
podList, err := podClient.List(listCtx, metav1.ListOptions{
|
||||||
LabelSelector: labelSelector,
|
LabelSelector: labelSelector,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,7 @@ func Run(runFilePath string, config runfileconfig.RunFileConfig) (bool, error) {
|
||||||
daprsyscall.SetupShutdownNotify(sigCh)
|
daprsyscall.SetupShutdownNotify(sigCh)
|
||||||
|
|
||||||
runStates := []runState{}
|
runStates := []runState{}
|
||||||
|
print.InfoStatusEvent(os.Stdout, "This is a preview feature and subject to change in future releases.")
|
||||||
|
|
||||||
for _, app := range config.Apps {
|
for _, app := range config.Apps {
|
||||||
print.StatusEvent(os.Stdout, print.LogInfo, "Validating config and starting app %q", app.RunConfig.AppID)
|
print.StatusEvent(os.Stdout, print.LogInfo, "Validating config and starting app %q", app.RunConfig.AppID)
|
||||||
|
|
@ -360,7 +361,11 @@ func writeYamlFile(app runfileconfig.App, svc serviceConfig, dep deploymentConfi
|
||||||
}
|
}
|
||||||
|
|
||||||
func deployYamlToK8s(yamlToDeployPath string) error {
|
func deployYamlToK8s(yamlToDeployPath string) error {
|
||||||
_, err := utils.RunCmdAndWait("kubectl", "apply", "-f", yamlToDeployPath)
|
_, err := os.Stat(yamlToDeployPath)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return fmt.Errorf("error given file %q does not exist", yamlToDeployPath)
|
||||||
|
}
|
||||||
|
_, err = utils.RunCmdAndWait("kubectl", "apply", "-f", yamlToDeployPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error deploying the yaml %s to Kubernetes: %w", yamlToDeployPath, err)
|
return fmt.Errorf("error deploying the yaml %s to Kubernetes: %w", yamlToDeployPath, err)
|
||||||
}
|
}
|
||||||
|
|
@ -369,9 +374,13 @@ func deployYamlToK8s(yamlToDeployPath string) error {
|
||||||
|
|
||||||
func deleteYamlK8s(yamlToDeletePath string) error {
|
func deleteYamlK8s(yamlToDeletePath string) error {
|
||||||
print.InfoStatusEvent(os.Stdout, "Deleting %q from Kubernetes", yamlToDeletePath)
|
print.InfoStatusEvent(os.Stdout, "Deleting %q from Kubernetes", yamlToDeletePath)
|
||||||
_, err := utils.RunCmdAndWait("kubectl", "delete", "-f", yamlToDeletePath)
|
_, err := os.Stat(yamlToDeletePath)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return fmt.Errorf("error given file %q does not exist", yamlToDeletePath)
|
||||||
|
}
|
||||||
|
_, err = utils.RunCmdAndWait("kubectl", "delete", "-f", yamlToDeletePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error deploying the yaml %s to Kubernetes: %w", yamlToDeletePath, err)
|
return fmt.Errorf("error deleting the yaml %s from Kubernetes: %w", yamlToDeletePath, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -401,7 +410,10 @@ func gracefullyShutdownK8sDeployment(runStates []runState, client k8s.Interface,
|
||||||
}
|
}
|
||||||
|
|
||||||
// shutdown logs.
|
// shutdown logs.
|
||||||
r.logCancel()
|
if r.logCancel != nil { // checking nil, in scenarios where deployments are not run correctly.
|
||||||
|
r.logCancel()
|
||||||
|
}
|
||||||
|
|
||||||
errs = append(errs, r.app.CloseAppLogFile(), r.app.CloseDaprdLogFile())
|
errs = append(errs, r.app.CloseAppLogFile(), r.app.CloseDaprdLogFile())
|
||||||
}
|
}
|
||||||
return errors.Join(errs...)
|
return errors.Join(errs...)
|
||||||
|
|
@ -413,14 +425,14 @@ func monitorK8sPods(ctx context.Context, client k8s.Interface, namespace string,
|
||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
|
|
||||||
for _, r := range runStates {
|
for _, r := range runStates {
|
||||||
|
wg.Add(1)
|
||||||
go func(appID string, wg *sync.WaitGroup) {
|
go func(appID string, wg *sync.WaitGroup) {
|
||||||
err := waitPodDeleted(ctx, client, namespace, r.app.AppID)
|
err := waitPodDeleted(ctx, client, namespace, appID)
|
||||||
if err != nil && strings.Contains(err.Error(), podWatchErrTemplate) {
|
if err != nil && strings.Contains(err.Error(), podWatchErrTemplate) {
|
||||||
print.WarningStatusEvent(os.Stderr, "Error monitoring Kubernetes pod(s) for app %q.", appID)
|
print.WarningStatusEvent(os.Stderr, "Error monitoring Kubernetes pod(s) for app %q.", appID)
|
||||||
}
|
}
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}(r.app.AppID, &wg)
|
}(r.app.AppID, &wg)
|
||||||
wg.Add(1)
|
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
// Send signal to gracefully close log writers and shut down process.
|
// Send signal to gracefully close log writers and shut down process.
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,12 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
|
||||||
|
"github.com/dapr/cli/pkg/print"
|
||||||
"github.com/dapr/cli/pkg/runfileconfig"
|
"github.com/dapr/cli/pkg/runfileconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -32,20 +34,34 @@ func Stop(runFilePath string, config runfileconfig.RunFileConfig) error {
|
||||||
return fmt.Errorf("error getting k8s client for monitoring pod deletion: %w", cErr)
|
return fmt.Errorf("error getting k8s client for monitoring pod deletion: %w", cErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
namespace := corev1.NamespaceDefault
|
namespace := corev1.NamespaceDefault
|
||||||
for _, app := range config.Apps {
|
for _, app := range config.Apps {
|
||||||
|
appError := false
|
||||||
deployDir := app.GetDeployDir()
|
deployDir := app.GetDeployDir()
|
||||||
serviceFilePath := filepath.Join(deployDir, serviceFileName)
|
serviceFilePath := filepath.Join(deployDir, serviceFileName)
|
||||||
deploymentFilePath := filepath.Join(deployDir, deploymentFileName)
|
deploymentFilePath := filepath.Join(deployDir, deploymentFileName)
|
||||||
if app.CreateService {
|
if app.CreateService {
|
||||||
errs = append(errs, deleteYamlK8s(serviceFilePath))
|
err = deleteYamlK8s(serviceFilePath)
|
||||||
|
if err != nil {
|
||||||
|
appError = true
|
||||||
|
}
|
||||||
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
errs = append(errs, deleteYamlK8s(deploymentFilePath))
|
err = deleteYamlK8s(deploymentFilePath)
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), podCreationDeletionTimeout)
|
if err != nil {
|
||||||
|
appError = true
|
||||||
|
}
|
||||||
|
errs = append(errs, err)
|
||||||
|
if !appError {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), podCreationDeletionTimeout)
|
||||||
|
|
||||||
// Ignoring errors here as it will anyway be printed in the other dapr cli process.
|
// Ignoring errors here as it will anyway be printed in the other dapr cli process.
|
||||||
waitPodDeleted(ctx, client, namespace, app.AppID)
|
waitPodDeleted(ctx, client, namespace, app.AppID)
|
||||||
cancel()
|
cancel()
|
||||||
|
} else {
|
||||||
|
print.WarningStatusEvent(os.Stderr, "Error stopping deployment for app %q in file %q", app.AppID, runFilePath)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return errors.Join(errs...)
|
return errors.Join(errs...)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ func UpgradeTest(details VersionDetails, opts TestOptions) func(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func EnsureUninstall(all bool) (string, error) {
|
func EnsureUninstall(all bool, devEnabled bool) (string, error) {
|
||||||
daprPath := GetDaprPath()
|
daprPath := GetDaprPath()
|
||||||
|
|
||||||
var _command [10]string
|
var _command [10]string
|
||||||
|
|
@ -153,6 +153,9 @@ func EnsureUninstall(all bool) (string, error) {
|
||||||
if all {
|
if all {
|
||||||
command = append(command, "--all")
|
command = append(command, "--all")
|
||||||
}
|
}
|
||||||
|
if devEnabled {
|
||||||
|
command = append(command, "--dev")
|
||||||
|
}
|
||||||
|
|
||||||
command = append(command,
|
command = append(command,
|
||||||
"-n", DaprTestNamespace,
|
"-n", DaprTestNamespace,
|
||||||
|
|
@ -179,6 +182,14 @@ func DeleteCRD(crds []string) func(*testing.T) {
|
||||||
|
|
||||||
// Get Test Cases.
|
// Get Test Cases.
|
||||||
|
|
||||||
|
func GetInstallOnlyTest(details VersionDetails, opts TestOptions) TestCase {
|
||||||
|
return TestCase{"install " + details.RuntimeVersion, installTest(details, opts)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetUninstallOnlyTest(details VersionDetails, opts TestOptions) TestCase {
|
||||||
|
return TestCase{"uninstall " + details.RuntimeVersion, uninstallTest(opts.UninstallAll, opts.DevEnabled)} // waits for pod deletion.
|
||||||
|
}
|
||||||
|
|
||||||
func GetTestsOnInstall(details VersionDetails, opts TestOptions) []TestCase {
|
func GetTestsOnInstall(details VersionDetails, opts TestOptions) []TestCase {
|
||||||
return []TestCase{
|
return []TestCase{
|
||||||
{"install " + details.RuntimeVersion, installTest(details, opts)},
|
{"install " + details.RuntimeVersion, installTest(details, opts)},
|
||||||
|
|
@ -799,7 +810,7 @@ func installTest(details VersionDetails, opts TestOptions) func(t *testing.T) {
|
||||||
|
|
||||||
func uninstallTest(all bool, devEnabled bool) func(t *testing.T) {
|
func uninstallTest(all bool, devEnabled bool) func(t *testing.T) {
|
||||||
return func(t *testing.T) {
|
return func(t *testing.T) {
|
||||||
output, err := EnsureUninstall(all)
|
output, err := EnsureUninstall(all, devEnabled)
|
||||||
t.Log(output)
|
t.Log(output)
|
||||||
require.NoError(t, err, "uninstall failed")
|
require.NoError(t, err, "uninstall failed")
|
||||||
// wait for pods to be deleted completely.
|
// wait for pods to be deleted completely.
|
||||||
|
|
@ -833,7 +844,7 @@ func uninstallTest(all bool, devEnabled bool) func(t *testing.T) {
|
||||||
|
|
||||||
func kubernetesTestOnUninstall() func(t *testing.T) {
|
func kubernetesTestOnUninstall() func(t *testing.T) {
|
||||||
return func(t *testing.T) {
|
return func(t *testing.T) {
|
||||||
_, err := EnsureUninstall(true)
|
_, err := EnsureUninstall(true, true)
|
||||||
require.NoError(t, err, "uninstall failed")
|
require.NoError(t, err, "uninstall failed")
|
||||||
daprPath := GetDaprPath()
|
daprPath := GetDaprPath()
|
||||||
output, err := spawn.Command(daprPath, "uninstall", "-k")
|
output, err := spawn.Command(daprPath, "uninstall", "-k")
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
//go:build e2e || templatek8s
|
||||||
|
// +build e2e templatek8s
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2021 The Dapr Authors
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kubernetes_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/dapr/cli/tests/e2e/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
currentRuntimeVersion string
|
||||||
|
currentDashboardVersion string
|
||||||
|
currentVersionDetails common.VersionDetails
|
||||||
|
clusterRoles1_9_X = []string{"dapr-operator-admin", "dashboard-reader"}
|
||||||
|
clusterRoleBindings1_9_X = []string{"dapr-operator", "dapr-role-tokenreview-binding", "dashboard-reader-global"}
|
||||||
|
clusterRoles1_10_X = []string{"dapr-dashboard", "dapr-injector", "dapr-operator-admin", "dapr-placement", "dapr-sentry"}
|
||||||
|
clusterRoleBindings1_10_X = []string{"dapr-operator-admin", "dapr-dashboard", "dapr-injector", "dapr-placement", "dapr-sentry"}
|
||||||
|
)
|
||||||
|
|
||||||
|
// ensureCleanEnv function needs to be called in every Test function.
|
||||||
|
// sets necessary variable values and uninstalls any previously installed `dapr`.
|
||||||
|
func ensureCleanEnv(t *testing.T, useDaprLatestVersion bool) {
|
||||||
|
currentRuntimeVersion, currentDashboardVersion = common.GetVersionsFromEnv(t, useDaprLatestVersion)
|
||||||
|
|
||||||
|
currentVersionDetails = common.VersionDetails{
|
||||||
|
RuntimeVersion: currentRuntimeVersion,
|
||||||
|
DashboardVersion: currentDashboardVersion,
|
||||||
|
CustomResourceDefs: []string{"components.dapr.io", "configurations.dapr.io", "subscriptions.dapr.io", "resiliencies.dapr.io", "httpendpoints.dapr.io"},
|
||||||
|
ImageVariant: "",
|
||||||
|
UseDaprLatestVersion: useDaprLatestVersion,
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(currentRuntimeVersion, "1.9.") {
|
||||||
|
currentVersionDetails.ClusterRoles = clusterRoles1_9_X
|
||||||
|
currentVersionDetails.ClusterRoleBindings = clusterRoleBindings1_9_X
|
||||||
|
} else {
|
||||||
|
currentVersionDetails.ClusterRoles = clusterRoles1_10_X
|
||||||
|
currentVersionDetails.ClusterRoleBindings = clusterRoleBindings1_10_X
|
||||||
|
}
|
||||||
|
// Ensure a clean environment
|
||||||
|
common.EnsureUninstall(true, true) // does not wait for pod deletion
|
||||||
|
}
|
||||||
|
|
@ -17,45 +17,11 @@ limitations under the License.
|
||||||
package kubernetes_test
|
package kubernetes_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/dapr/cli/tests/e2e/common"
|
"github.com/dapr/cli/tests/e2e/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
currentRuntimeVersion string
|
|
||||||
currentDashboardVersion string
|
|
||||||
currentVersionDetails common.VersionDetails
|
|
||||||
clusterRoles1_9_X = []string{"dapr-operator-admin", "dashboard-reader"}
|
|
||||||
clusterRoleBindings1_9_X = []string{"dapr-operator", "dapr-role-tokenreview-binding", "dashboard-reader-global"}
|
|
||||||
clusterRoles1_10_X = []string{"dapr-dashboard", "dapr-injector", "dapr-operator-admin", "dapr-placement", "dapr-sentry"}
|
|
||||||
clusterRoleBindings1_10_X = []string{"dapr-operator-admin", "dapr-dashboard", "dapr-injector", "dapr-placement", "dapr-sentry"}
|
|
||||||
)
|
|
||||||
|
|
||||||
// ensureCleanEnv function needs to be called in every Test function.
|
|
||||||
// sets necessary variable values and uninstalls any previously installed `dapr`.
|
|
||||||
func ensureCleanEnv(t *testing.T, useDaprLatestVersion bool) {
|
|
||||||
currentRuntimeVersion, currentDashboardVersion = common.GetVersionsFromEnv(t, useDaprLatestVersion)
|
|
||||||
|
|
||||||
currentVersionDetails = common.VersionDetails{
|
|
||||||
RuntimeVersion: currentRuntimeVersion,
|
|
||||||
DashboardVersion: currentDashboardVersion,
|
|
||||||
CustomResourceDefs: []string{"components.dapr.io", "configurations.dapr.io", "subscriptions.dapr.io", "resiliencies.dapr.io", "httpendpoints.dapr.io"},
|
|
||||||
ImageVariant: "",
|
|
||||||
UseDaprLatestVersion: useDaprLatestVersion,
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(currentRuntimeVersion, "1.9.") {
|
|
||||||
currentVersionDetails.ClusterRoles = clusterRoles1_9_X
|
|
||||||
currentVersionDetails.ClusterRoleBindings = clusterRoleBindings1_9_X
|
|
||||||
} else {
|
|
||||||
currentVersionDetails.ClusterRoles = clusterRoles1_10_X
|
|
||||||
currentVersionDetails.ClusterRoleBindings = clusterRoleBindings1_10_X
|
|
||||||
}
|
|
||||||
// Ensure a clean environment
|
|
||||||
common.EnsureUninstall(true) // does not wait for pod deletion
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestKubernetesNonHAModeMTLSDisabled(t *testing.T) {
|
func TestKubernetesNonHAModeMTLSDisabled(t *testing.T) {
|
||||||
// ensure clean env for test
|
// ensure clean env for test
|
||||||
ensureCleanEnv(t, false)
|
ensureCleanEnv(t, false)
|
||||||
|
|
@ -393,7 +359,7 @@ func TestKubernetesUninstall(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRenewCertWithIncorrectFlags(t *testing.T) {
|
func TestRenewCertWithIncorrectFlags(t *testing.T) {
|
||||||
common.EnsureUninstall(true)
|
common.EnsureUninstall(true, true)
|
||||||
|
|
||||||
tests := []common.TestCase{}
|
tests := []common.TestCase{}
|
||||||
installOpts := common.TestOptions{
|
installOpts := common.TestOptions{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,233 @@
|
||||||
|
//go:build e2e || templatek8s
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2023 The Dapr Authors
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kubernetes_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/dapr/cli/tests/e2e/common"
|
||||||
|
"github.com/dapr/cli/tests/e2e/spawn"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
waitForRunOutput = 60 * time.Second
|
||||||
|
windowsOsType = "windows"
|
||||||
|
serviceYamlFile = "service.yaml"
|
||||||
|
deploymentYamlFile = "deployment.yaml"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
nodeAppBaseDaprDir = filepath.Join("..", "..", "apps", "nodeapp", ".dapr")
|
||||||
|
pythonAppBaseDaprDir = filepath.Join("..", "..", "apps", "pythonapp", ".dapr")
|
||||||
|
nodeAppLogsDir = filepath.Join(nodeAppBaseDaprDir, "logs")
|
||||||
|
pythonAppLogsDir = filepath.Join(pythonAppBaseDaprDir, "logs")
|
||||||
|
nodeAppDeployDir = filepath.Join(nodeAppBaseDaprDir, "deploy")
|
||||||
|
pythonappDeployDir = filepath.Join(pythonAppBaseDaprDir, "deploy")
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestKubernetesRunFile(t *testing.T) {
|
||||||
|
ensureCleanEnv(t, false)
|
||||||
|
|
||||||
|
// setup tests
|
||||||
|
tests := []common.TestCase{}
|
||||||
|
opts := common.TestOptions{
|
||||||
|
DevEnabled: true,
|
||||||
|
HAEnabled: false,
|
||||||
|
MTLSEnabled: true,
|
||||||
|
}
|
||||||
|
tests = append(tests, common.GetInstallOnlyTest(currentVersionDetails, opts))
|
||||||
|
|
||||||
|
tests = append(tests, common.TestCase{
|
||||||
|
Name: "run file k8s",
|
||||||
|
Callable: testRunFile(common.TestOptions{}),
|
||||||
|
})
|
||||||
|
|
||||||
|
opts = common.TestOptions{
|
||||||
|
DevEnabled: true,
|
||||||
|
UninstallAll: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
tests = append(tests, common.GetUninstallOnlyTest(currentVersionDetails, opts))
|
||||||
|
|
||||||
|
// execute tests
|
||||||
|
for _, tc := range tests {
|
||||||
|
t.Run(tc.Name, tc.Callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testRunFile(opts common.TestOptions) func(t *testing.T) {
|
||||||
|
return func(t *testing.T) {
|
||||||
|
// File present as part of "tests/e2e/testdata" folder.
|
||||||
|
runFilePath := filepath.Join("..", "testdata", "run-template-files", "dapr-k8s.yaml")
|
||||||
|
t.Cleanup(func() {
|
||||||
|
// assumption in the test is that there is only one set of app and daprd logs in the logs directory.
|
||||||
|
os.RemoveAll(nodeAppLogsDir)
|
||||||
|
os.RemoveAll(pythonAppLogsDir)
|
||||||
|
stopAllApps(t, runFilePath)
|
||||||
|
})
|
||||||
|
go startAppsWithTemplateFile(t, runFilePath)
|
||||||
|
time.Sleep(waitForRunOutput)
|
||||||
|
|
||||||
|
// assert yaml files created.
|
||||||
|
assert.FileExists(t, filepath.Join(nodeAppDeployDir, serviceYamlFile), "service yaml must exist for node app")
|
||||||
|
assert.FileExists(t, filepath.Join(nodeAppDeployDir, deploymentYamlFile), "deployment yaml must exist for node app")
|
||||||
|
|
||||||
|
assert.FileExists(t, filepath.Join(pythonappDeployDir, deploymentYamlFile), "deployment yaml must exist for python app")
|
||||||
|
|
||||||
|
_, err := cmdStopWithRunTemplate(runFilePath)
|
||||||
|
assert.NoError(t, err, "failed to stop apps started with run template")
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
|
||||||
|
// For Node app
|
||||||
|
daprdLogFile, err := lookUpFileFullName(nodeAppLogsDir, "daprd")
|
||||||
|
require.NoError(t, err, "expected no error in finding the daprd log file for node app")
|
||||||
|
contents := []string{
|
||||||
|
"dapr initialized. Status: Running.",
|
||||||
|
"app_id=nodeapp",
|
||||||
|
"Shutting down all remaining components",
|
||||||
|
}
|
||||||
|
assertLogFileContains(t, filepath.Join(nodeAppLogsDir, daprdLogFile), contents)
|
||||||
|
|
||||||
|
appLogFile, err := lookUpFileFullName(nodeAppLogsDir, "app")
|
||||||
|
require.NoError(t, err, "expected no error in finding the app log file for node app")
|
||||||
|
contents = []string{
|
||||||
|
"== APP - nodeapp == Node App listening on port 3000!",
|
||||||
|
// not specifying any order ID as it is non-deterministic and dependent on network and OS.
|
||||||
|
"== APP - nodeapp == Got a new order! Order ID:",
|
||||||
|
"== APP - nodeapp == Successfully persisted state for Order ID:",
|
||||||
|
}
|
||||||
|
assertLogFileContains(t, filepath.Join(nodeAppLogsDir, appLogFile), contents)
|
||||||
|
|
||||||
|
// For Python app
|
||||||
|
|
||||||
|
daprdLogFile, err = lookUpFileFullName(pythonAppLogsDir, "daprd")
|
||||||
|
require.NoError(t, err, "expected no error in finding the daprd log file for python app")
|
||||||
|
contents = []string{
|
||||||
|
"dapr initialized. Status: Running.",
|
||||||
|
"app_id=pythonapp",
|
||||||
|
"Shutting down all remaining components",
|
||||||
|
}
|
||||||
|
assertLogFileContains(t, filepath.Join(pythonAppLogsDir, daprdLogFile), contents)
|
||||||
|
|
||||||
|
appLogFile, err = lookUpFileFullName(pythonAppLogsDir, "app")
|
||||||
|
require.NoError(t, err, "expected no error in finding the app log file for python app")
|
||||||
|
contents = []string{
|
||||||
|
// logs during shutdown sequence.
|
||||||
|
"== APP - pythonapp == HTTP 500 => {\"errorCode\":\"ERR_DIRECT_INVOKE\",\"message\":\"fail to invoke, id: nodeapp",
|
||||||
|
}
|
||||||
|
assertLogFileContains(t, filepath.Join(pythonAppLogsDir, appLogFile), contents)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startAppsWithTemplateFile(t *testing.T, runFilePath string) {
|
||||||
|
// All apps are withing "tests/apps" folder.
|
||||||
|
args := []string{
|
||||||
|
"-f", runFilePath,
|
||||||
|
"-k",
|
||||||
|
}
|
||||||
|
output, err := cmdRun(args...)
|
||||||
|
t.Logf(output)
|
||||||
|
require.NoError(t, err, "run failed")
|
||||||
|
assert.Contains(t, output, "Deploying service YAML")
|
||||||
|
assert.Contains(t, output, "Deploying deployment YAML")
|
||||||
|
|
||||||
|
assert.Contains(t, output, "This is a preview feature and subject to change in future releases.")
|
||||||
|
assert.Contains(t, output, "Validating config and starting app \"nodeapp\"")
|
||||||
|
assert.Contains(t, output, "Deploying app \"nodeapp\" to Kubernetes")
|
||||||
|
if runtime.GOOS == windowsOsType {
|
||||||
|
assert.Contains(t, output, "tests\\apps\\nodeapp\\.dapr\\deploy\\service.yaml\" to Kubernetes")
|
||||||
|
} else {
|
||||||
|
assert.Contains(t, output, "tests/apps/nodeapp/.dapr/deploy/service.yaml")
|
||||||
|
}
|
||||||
|
|
||||||
|
if runtime.GOOS == windowsOsType {
|
||||||
|
assert.Contains(t, output, "tests\\apps\\nodeapp\\.dapr\\deploy\\deployment.yaml\" to Kubernetes")
|
||||||
|
} else {
|
||||||
|
assert.Contains(t, output, "tests/apps/nodeapp/.dapr/deploy/deployment.yaml\" to Kubernetes")
|
||||||
|
}
|
||||||
|
assert.Contains(t, output, "Streaming logs for containers in pod \"nodeapp-")
|
||||||
|
if runtime.GOOS == windowsOsType {
|
||||||
|
assert.Contains(t, output, "tests\\apps\\nodeapp\\.dapr\\logs")
|
||||||
|
} else {
|
||||||
|
assert.Contains(t, output, "tests/apps/nodeapp/.dapr/logs")
|
||||||
|
}
|
||||||
|
assert.Contains(t, output, "Validating config and starting app \"pythonapp\"")
|
||||||
|
if runtime.GOOS == windowsOsType {
|
||||||
|
assert.Contains(t, output, "tests\\apps\\pythonapp\\.dapr\\deploy\\deployment.yaml\" to Kubernetes")
|
||||||
|
} else {
|
||||||
|
assert.Contains(t, output, "tests/apps/pythonapp/.dapr/deploy/deployment.yaml\" to Kubernetes")
|
||||||
|
}
|
||||||
|
assert.Contains(t, output, "Streaming logs for containers in pod \"pythonapp-")
|
||||||
|
if runtime.GOOS == windowsOsType {
|
||||||
|
assert.Contains(t, output, "tests\\apps\\pythonapp\\.dapr\\logs")
|
||||||
|
} else {
|
||||||
|
assert.Contains(t, output, "tests/apps/pythonapp/.dapr/logs")
|
||||||
|
}
|
||||||
|
assert.Contains(t, output, "Starting to monitor Kubernetes pods for deletion.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// cmdRun runs a Dapr instance and returns the command output and error.
|
||||||
|
func cmdRun(args ...string) (string, error) {
|
||||||
|
runArgs := []string{"run"}
|
||||||
|
|
||||||
|
runArgs = append(runArgs, args...)
|
||||||
|
return spawn.Command(common.GetDaprPath(), runArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// cmdStopWithRunTemplate stops the apps started with run template file and returns the command output and error.
|
||||||
|
func cmdStopWithRunTemplate(runTemplateFile string, args ...string) (string, error) {
|
||||||
|
stopArgs := append([]string{"stop", "--log-as-json", "-k", "-f", runTemplateFile}, args...)
|
||||||
|
return spawn.Command(common.GetDaprPath(), stopArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertLogFileContains(t *testing.T, logFilePath string, expectedContent []string) {
|
||||||
|
assert.FileExists(t, logFilePath, "log file %s must exist", logFilePath)
|
||||||
|
fileContents, err := os.ReadFile(logFilePath)
|
||||||
|
assert.NoError(t, err, "failed to read %s log", logFilePath)
|
||||||
|
contentString := string(fileContents)
|
||||||
|
for _, line := range expectedContent {
|
||||||
|
assert.Contains(t, contentString, line, "expected logline to be present")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// lookUpFileFullName looks up the full name of the first file with partial name match in the directory.
|
||||||
|
func lookUpFileFullName(dirPath, partialFilename string) (string, error) {
|
||||||
|
// Look for the file in the current directory
|
||||||
|
files, err := os.ReadDir(dirPath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
for _, file := range files {
|
||||||
|
if strings.Contains(file.Name(), partialFilename) {
|
||||||
|
return file.Name(), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("failed to find file with partial name %s in directory %s", partialFilename, dirPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func stopAllApps(t *testing.T, runfile string) {
|
||||||
|
_, err := cmdStopWithRunTemplate(runfile)
|
||||||
|
require.NoError(t, err, "failed to stop apps")
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
}
|
||||||
|
|
@ -119,7 +119,7 @@ func cmdRun(unixDomainSocket string, args ...string) (string, error) {
|
||||||
return spawn.Command(common.GetDaprPath(), runArgs...)
|
return spawn.Command(common.GetDaprPath(), runArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// cmdRun runs a Dapr instance and returns the command output and error.
|
// cmdRunWithContext runs a Dapr instance with context and returns the command output and error.
|
||||||
func cmdRunWithContext(ctx context.Context, unixDomainSocket string, args ...string) (string, error) {
|
func cmdRunWithContext(ctx context.Context, unixDomainSocket string, args ...string) (string, error) {
|
||||||
runArgs := []string{"run"}
|
runArgs := []string{"run"}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
version: 1
|
version: 1
|
||||||
|
name: dapr-k8s-tes-yaml
|
||||||
common:
|
common:
|
||||||
apps:
|
apps:
|
||||||
- appDirPath: ./nodeapp/
|
- appDirPath: ../../../apps/nodeapp/
|
||||||
appPort: 3000
|
appPort: 3000
|
||||||
containerImage: ghcr.io/dapr/samples/hello-k8s-node:latest
|
containerImage: ghcr.io/dapr/samples/hello-k8s-node:latest
|
||||||
createService: true
|
createService: true
|
||||||
env:
|
env:
|
||||||
APP_PORT: 3000
|
APP_PORT: 3000
|
||||||
- appDirPath: ./pythonapp/
|
- appDirPath: ../../../apps/pythonapp/
|
||||||
containerImage: ghcr.io/dapr/samples/hello-k8s-python:latest
|
containerImage: ghcr.io/dapr/samples/hello-k8s-python:latest
|
||||||
|
|
@ -138,7 +138,7 @@ func getTestsOnUpgrade(p upgradePath, installOpts, upgradeOpts common.TestOption
|
||||||
|
|
||||||
func TestUpgradePathNonHAModeMTLSDisabled(t *testing.T) {
|
func TestUpgradePathNonHAModeMTLSDisabled(t *testing.T) {
|
||||||
// Ensure a clean environment.
|
// Ensure a clean environment.
|
||||||
common.EnsureUninstall(false) // does not wait for pod deletion.
|
common.EnsureUninstall(false, false) // does not wait for pod deletion.
|
||||||
for _, p := range supportedUpgradePaths {
|
for _, p := range supportedUpgradePaths {
|
||||||
t.Run(fmt.Sprintf("setup v%s to v%s", p.previous.RuntimeVersion, p.next.RuntimeVersion), func(t *testing.T) {
|
t.Run(fmt.Sprintf("setup v%s to v%s", p.previous.RuntimeVersion, p.next.RuntimeVersion), func(t *testing.T) {
|
||||||
t.Run("delete CRDs "+p.previous.RuntimeVersion, common.DeleteCRD(p.previous.CustomResourceDefs))
|
t.Run("delete CRDs "+p.previous.RuntimeVersion, common.DeleteCRD(p.previous.CustomResourceDefs))
|
||||||
|
|
@ -183,7 +183,7 @@ func TestUpgradePathNonHAModeMTLSDisabled(t *testing.T) {
|
||||||
|
|
||||||
func TestUpgradePathNonHAModeMTLSEnabled(t *testing.T) {
|
func TestUpgradePathNonHAModeMTLSEnabled(t *testing.T) {
|
||||||
// Ensure a clean environment.
|
// Ensure a clean environment.
|
||||||
common.EnsureUninstall(false) // does not wait for pod deletion.
|
common.EnsureUninstall(false, false) // does not wait for pod deletion.
|
||||||
for _, p := range supportedUpgradePaths {
|
for _, p := range supportedUpgradePaths {
|
||||||
t.Run(fmt.Sprintf("setup v%s to v%s", p.previous.RuntimeVersion, p.next.RuntimeVersion), func(t *testing.T) {
|
t.Run(fmt.Sprintf("setup v%s to v%s", p.previous.RuntimeVersion, p.next.RuntimeVersion), func(t *testing.T) {
|
||||||
t.Run("delete CRDs "+p.previous.RuntimeVersion, common.DeleteCRD(p.previous.CustomResourceDefs))
|
t.Run("delete CRDs "+p.previous.RuntimeVersion, common.DeleteCRD(p.previous.CustomResourceDefs))
|
||||||
|
|
@ -228,7 +228,7 @@ func TestUpgradePathNonHAModeMTLSEnabled(t *testing.T) {
|
||||||
|
|
||||||
func TestUpgradePathHAModeMTLSDisabled(t *testing.T) {
|
func TestUpgradePathHAModeMTLSDisabled(t *testing.T) {
|
||||||
// Ensure a clean environment.
|
// Ensure a clean environment.
|
||||||
common.EnsureUninstall(false) // does not wait for pod deletion.
|
common.EnsureUninstall(false, false) // does not wait for pod deletion.
|
||||||
for _, p := range supportedUpgradePaths {
|
for _, p := range supportedUpgradePaths {
|
||||||
t.Run(fmt.Sprintf("setup v%s to v%s", p.previous.RuntimeVersion, p.next.RuntimeVersion), func(t *testing.T) {
|
t.Run(fmt.Sprintf("setup v%s to v%s", p.previous.RuntimeVersion, p.next.RuntimeVersion), func(t *testing.T) {
|
||||||
t.Run("delete CRDs "+p.previous.RuntimeVersion, common.DeleteCRD(p.previous.CustomResourceDefs))
|
t.Run("delete CRDs "+p.previous.RuntimeVersion, common.DeleteCRD(p.previous.CustomResourceDefs))
|
||||||
|
|
@ -273,7 +273,7 @@ func TestUpgradePathHAModeMTLSDisabled(t *testing.T) {
|
||||||
|
|
||||||
func TestUpgradePathHAModeMTLSEnabled(t *testing.T) {
|
func TestUpgradePathHAModeMTLSEnabled(t *testing.T) {
|
||||||
// Ensure a clean environment.
|
// Ensure a clean environment.
|
||||||
common.EnsureUninstall(false) // does not wait for pod deletion.
|
common.EnsureUninstall(false, false) // does not wait for pod deletion.
|
||||||
for _, p := range supportedUpgradePaths {
|
for _, p := range supportedUpgradePaths {
|
||||||
t.Run(fmt.Sprintf("setup v%s to v%s", p.previous.RuntimeVersion, p.next.RuntimeVersion), func(t *testing.T) {
|
t.Run(fmt.Sprintf("setup v%s to v%s", p.previous.RuntimeVersion, p.next.RuntimeVersion), func(t *testing.T) {
|
||||||
t.Run("delete CRDs "+p.previous.RuntimeVersion, common.DeleteCRD(p.previous.CustomResourceDefs))
|
t.Run("delete CRDs "+p.previous.RuntimeVersion, common.DeleteCRD(p.previous.CustomResourceDefs))
|
||||||
|
|
@ -320,7 +320,7 @@ func TestUpgradePathHAModeMTLSEnabled(t *testing.T) {
|
||||||
// This test verifies install/upgrade functionality with this additional resource.
|
// This test verifies install/upgrade functionality with this additional resource.
|
||||||
func TestUpgradeWithHTTPEndpoint(t *testing.T) {
|
func TestUpgradeWithHTTPEndpoint(t *testing.T) {
|
||||||
// Ensure a clean environment.
|
// Ensure a clean environment.
|
||||||
common.EnsureUninstall(false) // does not wait for pod deletion.
|
common.EnsureUninstall(false, false) // does not wait for pod deletion.
|
||||||
for _, p := range supportedUpgradePaths {
|
for _, p := range supportedUpgradePaths {
|
||||||
t.Run(fmt.Sprintf("setup v%s to v%s", p.previous.RuntimeVersion, p.next.RuntimeVersion), func(t *testing.T) {
|
t.Run(fmt.Sprintf("setup v%s to v%s", p.previous.RuntimeVersion, p.next.RuntimeVersion), func(t *testing.T) {
|
||||||
t.Run("delete CRDs "+p.previous.RuntimeVersion, common.DeleteCRD(p.previous.CustomResourceDefs))
|
t.Run("delete CRDs "+p.previous.RuntimeVersion, common.DeleteCRD(p.previous.CustomResourceDefs))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue