cli/tests/e2e/standalone/standalone_test.go

298 lines
7.1 KiB
Go

// +build e2e
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation and Dapr Contributors.
// Licensed under the MIT License.
// ------------------------------------------------------------
package standalone_test
import (
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v2"
"github.com/dapr/cli/tests/e2e/spawn"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
)
const (
daprNamespace = "dapr-cli-tests"
daprRuntimeVersion = "1.1.0"
daprDashboardVersion = "0.6.0"
)
func TestStandaloneInstall(t *testing.T) {
// Ensure a clean environment
uninstall()
tests := []struct {
name string
phase func(*testing.T)
}{
{"test install", testInstall},
{"test run", testRun},
{"test uninstall", testUninstall},
}
for _, tc := range tests {
t.Run(tc.name, tc.phase)
}
}
func getDaprPath() string {
distDir := fmt.Sprintf("%s_%s", runtime.GOOS, runtime.GOARCH)
return filepath.Join("..", "..", "..", "dist", distDir, "release", "dapr")
}
func uninstall() (string, error) {
daprPath := getDaprPath()
return spawn.Command(daprPath, "uninstall", "--all", "--log-as-json")
}
func testUninstall(t *testing.T) {
output, err := uninstall()
t.Log(output)
require.NoError(t, err, "uninstall failed")
homeDir, err := os.UserHomeDir()
require.NoError(t, err)
daprHome := filepath.Join(homeDir, ".dapr")
_, err = os.Stat(daprHome)
if assert.Error(t, err) {
assert.True(t, os.IsNotExist(err), err.Error())
}
// Verify Containers
cli, err := client.NewEnvClient()
require.NoError(t, err)
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
require.NoError(t, err)
notFound := map[string]string{
"dapr_placement": daprRuntimeVersion,
"dapr_zipkin": "",
"dapr_redis": "",
}
for _, container := range containers {
t.Logf("%v %s %s\n", container.Names, container.Image, container.State)
name := strings.TrimPrefix(container.Names[0], "/")
delete(notFound, name)
}
assert.Equal(t, 3, len(notFound))
}
func testInstall(t *testing.T) {
daprPath := getDaprPath()
output, err := spawn.Command(daprPath, "init", "--runtime-version", daprRuntimeVersion, "--log-as-json")
t.Log(output)
require.NoError(t, err, "init failed")
// Verify Containers
cli, err := client.NewEnvClient()
require.NoError(t, err)
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
require.NoError(t, err)
notFound := map[string]string{
"dapr_placement": daprRuntimeVersion,
"dapr_zipkin": "",
"dapr_redis": "",
}
for _, container := range containers {
t.Logf("%v %s %s\n", container.Names, container.Image, container.State)
if container.State != "running" {
continue
}
name := strings.TrimPrefix(container.Names[0], "/")
if expectedVersion, ok := notFound[name]; ok {
if expectedVersion != "" {
versionIndex := strings.LastIndex(container.Image, ":")
if versionIndex == -1 {
continue
}
version := container.Image[versionIndex+1:]
if version != expectedVersion {
continue
}
}
delete(notFound, name)
}
}
assert.Empty(t, notFound)
// Verify Binaries
homeDir, err := os.UserHomeDir()
require.NoError(t, err)
path := filepath.Join(homeDir, ".dapr")
binPath := filepath.Join(path, "bin")
binaries := map[string]string{
"daprd": daprRuntimeVersion,
"dashboard": daprDashboardVersion,
}
for bin, version := range binaries {
t.Run(bin, func(t *testing.T) {
file := filepath.Join(binPath, bin)
if runtime.GOOS == "windows" {
file += ".exe"
}
_, err := os.Stat(file)
if !assert.NoError(t, err) {
return
}
// Check version
output, err := spawn.Command(file, "--version")
if !assert.NoError(t, err) {
return
}
output = strings.TrimSpace(output)
if !assert.Equal(t, version, output) {
return
}
delete(binaries, bin)
})
}
assert.Empty(t, binaries)
// Verify configs
configs := map[string]map[string]interface{}{
"config.yaml": {
"apiVersion": "dapr.io/v1alpha1",
"kind": "Configuration",
"metadata": map[interface{}]interface{}{
"name": "daprConfig",
},
"spec": map[interface{}]interface{}{
"tracing": map[interface{}]interface{}{
"samplingRate": "1",
"zipkin": map[interface{}]interface{}{
"endpointAddress": "http://localhost:9411/api/v2/spans",
},
},
},
},
filepath.Join("components", "statestore.yaml"): {
"apiVersion": "dapr.io/v1alpha1",
"kind": "Component",
"metadata": map[interface{}]interface{}{
"name": "statestore",
},
"spec": map[interface{}]interface{}{
"type": "state.redis",
"version": "v1",
"metadata": []interface{}{
map[interface{}]interface{}{
"name": "redisHost",
"value": "localhost:6379",
},
map[interface{}]interface{}{
"name": "redisPassword",
"value": "",
},
map[interface{}]interface{}{
"name": "actorStateStore",
"value": "true",
},
},
},
},
filepath.Join("components", "pubsub.yaml"): {
"apiVersion": "dapr.io/v1alpha1",
"kind": "Component",
"metadata": map[interface{}]interface{}{
"name": "pubsub",
},
"spec": map[interface{}]interface{}{
"type": "pubsub.redis",
"version": "v1",
"metadata": []interface{}{
map[interface{}]interface{}{
"name": "redisHost",
"value": "localhost:6379",
},
map[interface{}]interface{}{
"name": "redisPassword",
"value": "",
},
},
},
},
}
for filename, contents := range configs {
t.Run(filename, func(t *testing.T) {
fullpath := filepath.Join(path, filename)
contentBytes, err := ioutil.ReadFile(fullpath)
if !assert.NoError(t, err) {
return
}
var actual map[string]interface{}
err = yaml.Unmarshal(contentBytes, &actual)
if !assert.NoError(t, err) {
return
}
if !assert.Equal(t, contents, actual) {
return
}
delete(configs, filename)
})
}
assert.Empty(t, configs)
}
func testRun(t *testing.T) {
daprPath := getDaprPath()
output, err := spawn.Command(daprPath, "run", "--", "bash", "-c", "echo test")
t.Log(output)
require.NoError(t, err, "run failed")
assert.Contains(t, output, "Exited App successfully")
assert.Contains(t, output, "Exited Dapr successfully")
output, err = spawn.Command(daprPath, "run", "--", "bash", "-c", "exit 1")
t.Log(output)
require.NoError(t, err, "run failed")
assert.Contains(t, output, "The App process exited with error code: exit status 1")
assert.Contains(t, output, "Exited Dapr successfully")
// Test that the CLI exits on a daprd shutdown.
output, err = spawn.Command(daprPath, "run", "--dapr-http-port", "9999", "--", "bash", "-c", "curl -v http://localhost:9999/v1.0/shutdown; sleep 10; exit 1")
t.Log(output)
require.NoError(t, err, "run failed")
assert.Contains(t, output, "Exited App successfully", "App should be shutdown before it has a chance to return non-zero")
assert.Contains(t, output, "Exited Dapr successfully")
}