Skip to content

Commit

Permalink
Add E2E for Run template (#1170)
Browse files Browse the repository at this point in the history
* refactor run into functions

Signed-off-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>

* renamed Apps struct as App

Signed-off-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>

* redirect logs to files. set informational logs. set command dirs

Signed-off-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>

* fix linter errors

Signed-off-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>

* fix e2e test on non-existent resources-path

Signed-off-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>

* more fixes

Signed-off-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>

* fix merge conflict

Signed-off-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>

* set default ports for zero values

Signed-off-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>

* fix linter errors

Signed-off-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>

* add more details in error, fix logs in run -f

Signed-off-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>

* address review comments

Signed-off-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>

* address review comments

Signed-off-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>

* add more fixes in template run based on e2e tests

Signed-off-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>

* add basic happy path e2e for dapr run -f

Signed-off-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>

* add positive and negative e2e tests for run template

Signed-off-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>

* address review comments

Signed-off-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>

Signed-off-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>
  • Loading branch information
mukundansundar authored Jan 24, 2023
1 parent 14c04f9 commit 17dbe5b
Show file tree
Hide file tree
Showing 26 changed files with 694 additions and 33 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ cli

# CLI's auto-generated components directory
**/components
# Auto generated logs dir inside .dapr directory
**/.dapr/logs

test_output.json

Expand Down
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ test: test-deps
################################################################################
.PHONY: test-e2e-k8s
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/...

################################################################################
# Build, E2E Tests for Kubernetes #
Expand All @@ -175,6 +175,13 @@ test-e2e-upgrade: test-deps
e2e-build-run-upgrade: build test-e2e-upgrade


################################################################################
# E2E Tests for Self-Hosted Template exec #
################################################################################
.PHONY: test-e2e-sh-template
test-e2e-sh-template: test-deps
gotestsum --jsonfile $(TEST_OUTPUT_FILE) --format standard-verbose -- -timeout $(E2E_SH_TEST_TIMEOUT) -count=1 -tags=template ./tests/e2e/standalone/...

################################################################################
# E2E Tests for Self-Hosted #
################################################################################
Expand Down
16 changes: 6 additions & 10 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ func executeRun(runFilePath string, apps []runfileconfig.App) (bool, error) {
runConfig := app.RunConfig
err = app.CreateDaprdLogFile()
if err != nil {
print.StatusEvent(os.Stderr, print.LogFailure, "Error getting log file for app %q present in %s: %s", runConfig.AppID, runFilePath, err.Error())
print.StatusEvent(os.Stderr, print.LogFailure, "Error getting daprd log file for app %q present in %s: %s", runConfig.AppID, runFilePath, err.Error())
exitWithError = true
break
}
Expand All @@ -490,7 +490,7 @@ func executeRun(runFilePath string, apps []runfileconfig.App) (bool, error) {
} else {
err = app.CreateAppLogFile()
if err != nil {
print.StatusEvent(os.Stderr, print.LogFailure, "Error getting log file for app %q present in %s: %s", runConfig.AppID, runFilePath, err.Error())
print.StatusEvent(os.Stderr, print.LogFailure, "Error getting app log file for app %q present in %s: %s", runConfig.AppID, runFilePath, err.Error())
exitWithError = true
break
}
Expand Down Expand Up @@ -531,7 +531,7 @@ func executeRun(runFilePath string, apps []runfileconfig.App) (bool, error) {
}

// Stop daprd and app processes for each runState.
_, closeError := gracefullyShutdownAppsAndCloseResources(runStates, apps)
closeError := gracefullyShutdownAppsAndCloseResources(runStates, apps)

for _, app := range apps {
runConfig := app.RunConfig
Expand All @@ -551,13 +551,9 @@ func logInformationalStatusToStdout(app runfileconfig.App) {
print.InfoStatusEvent(os.Stdout, "Writing log files to directory : %s", app.GetLogsDir())
}

func gracefullyShutdownAppsAndCloseResources(runState []*runExec.RunExec, apps []runfileconfig.App) (bool, error) {
exitWithError := false
func gracefullyShutdownAppsAndCloseResources(runState []*runExec.RunExec, apps []runfileconfig.App) error {
for _, s := range runState {
hasErr := stopDaprdAndAppProcesses(s)
if !exitWithError && hasErr {
exitWithError = true
}
stopDaprdAndAppProcesses(s)
}
var err error
// close log file resources.
Expand All @@ -571,7 +567,7 @@ func gracefullyShutdownAppsAndCloseResources(runState []*runExec.RunExec, apps [
err = hasErr
}
}
return exitWithError, err
return err
}

func executeRunWithAppsConfigFile(runFilePath string) {
Expand Down
77 changes: 77 additions & 0 deletions tests/apps/emit-metrics/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
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 main

import (
"bytes"
"encoding/json"
"log"
"net/http"
"os"
"time"
)

type Metrics struct {
MetricsID int `json:"metricsID"`
}

func main() {
var host string
var port string
client := http.Client{}
if val, ok := os.LookupEnv("DAPR_HTTP_PORT"); !ok {
log.Fatalf("DAPR_HTTP_PORT not automatically injected")
} else {
log.Println("DAPR_HTTP_PORT set to", val)
port = val
}
// DAPR_HOST_ADD needs to be an env set in dapr.yaml file
if val, ok := os.LookupEnv("DAPR_HOST_ADD"); !ok {
log.Fatalf("DAPR_HOST_ADD not set")
} else {
log.Println("DAPR_HOST_ADD set to", val)
host = val
}
finalURL := "http://" + host + ":" + port + "/metrics"
log.Println("Sending metrics to ", finalURL)
for i := 0; i < 2000; i++ {
time.Sleep(1 * time.Second)
metrics := Metrics{
MetricsID: i,
}
b, err := json.Marshal(metrics)
if err != nil {
log.Println("Got error while marshalling metrics ", err)
continue
}
// Send metrics to Dapr
req, _ := http.NewRequest(http.MethodPost, finalURL, bytes.NewBuffer(b))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("dapr-app-id", "processor")
r, err := client.Do(req)
if err != nil {
log.Println("Got error while sending a request to 'processor' app ", err)
continue
}
defer r.Body.Close()
if r.StatusCode != http.StatusOK {
log.Printf("Error sending metrics with %d to 'processor' app got status code %d\n", i, r.StatusCode)
log.Printf("Status %s \n", r.Status)
continue
}
log.Printf("Metrics with ID %d sent \n", i)
}
}
3 changes: 3 additions & 0 deletions tests/apps/emit-metrics/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module emit-metrics

go 1.19
87 changes: 87 additions & 0 deletions tests/apps/processor/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
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 main

import (
"context"
"encoding/json"
"fmt"
"log"
"net"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)

type handler struct{}

type Metrics struct {
MetricsID int `json:"metricsID"`
}

func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Println("Received request: ", r.Method)
defer r.Body.Close()
var metrics Metrics
err := json.NewDecoder(r.Body).Decode(&metrics)
if err != nil {
fmt.Println("Error decoding body: ", err)
w.WriteHeader(http.StatusBadRequest)
return
}
fmt.Println("Received metrics: ", metrics)
w.WriteHeader(http.StatusOK)
}

func main() {
fmt.Println("Starting server in port 9081...")
StartServer(9081, &handler{})
}

// StartServer starts a HTTP or HTTP2 server
func StartServer(port int, handler http.Handler) {
// Create a listener
addr := fmt.Sprintf(":%d", port)
ln, err := net.Listen("tcp", addr)
if err != nil {
log.Fatalf("Failed to create listener: %v", err)
}
//nolint:gosec
server := &http.Server{
Addr: addr,
Handler: handler,
}

// Stop the server when we get a termination signal
stopCh := make(chan os.Signal, 1)
signal.Notify(stopCh, syscall.SIGKILL, syscall.SIGTERM, syscall.SIGINT) //nolint:staticcheck
go func() {
// Wait for cancelation signal
<-stopCh
log.Println("Shutdown signal received")
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
server.Shutdown(ctx)
}()

err = server.Serve(ln)

if err != http.ErrServerClosed {
log.Fatalf("Failed to run server: %v", err)
}

log.Println("Server shut down")
}
3 changes: 3 additions & 0 deletions tests/apps/processor/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module processor

go 1.19
40 changes: 40 additions & 0 deletions tests/e2e/spawn/spawn.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ package spawn

import (
"bufio"
"bytes"
"context"
"fmt"
"os/exec"
"syscall"
"time"
)

// CommandWithContext runs a command with its arguments in background.
Expand Down Expand Up @@ -72,3 +76,39 @@ func Command(command string, arguments ...string) (string, error) {

return string(outBytes), err
}

// CommandExecWithContext runs a command with its arguments, kills the command after context is done
// and returns the combined stdout, stderr or the error.
func CommandExecWithContext(ctx context.Context, command string, arguments ...string) (string, error) {
cmd := exec.Command(command, arguments...)
var b bytes.Buffer
cmd.Stdout = &b
cmd.Stderr = &b

err := cmd.Start()
if err != nil {
return "", fmt.Errorf("error starting command : %w", err)
}

waitErrChan := make(chan error, 1)
go func(errChan chan error) {
waitErr := cmd.Wait()
if waitErr != nil {
fmt.Printf("error waiting for command : %s\n", waitErr)
}
waitErrChan <- waitErr
}(waitErrChan)
<-ctx.Done()
if cmd.ProcessState == nil || !cmd.ProcessState.Exited() {
cmd.Process.Signal(syscall.SIGTERM)
time.Sleep(10 * time.Second)
if cmd.ProcessState == nil || !cmd.ProcessState.Exited() {
err = cmd.Process.Kill()
if err != nil {
return b.String(), fmt.Errorf("error killing command : %w", err)
}
}
}

return b.String(), <-waitErrChan
}
16 changes: 14 additions & 2 deletions tests/e2e/standalone/commands.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build e2e
// +build e2e
//go:build e2e || template
// +build e2e template

/*
Copyright 2022 The Dapr Authors
Expand Down Expand Up @@ -119,6 +119,18 @@ func cmdRun(unixDomainSocket string, args ...string) (string, error) {
return spawn.Command(common.GetDaprPath(), runArgs...)
}

// cmdRun runs a Dapr instance and returns the command output and error.
func cmdRunWithContext(ctx context.Context, unixDomainSocket string, args ...string) (string, error) {
runArgs := []string{"run"}

if unixDomainSocket != "" {
runArgs = append(runArgs, "--unix-domain-socket", unixDomainSocket)
}

runArgs = append(runArgs, args...)
return spawn.CommandExecWithContext(ctx, common.GetDaprPath(), runArgs...)
}

// cmdStop stops the specified app and returns the command output and error.
func cmdStop(appId string, args ...string) (string, error) {
stopArgs := append([]string{"stop", "--log-as-json", "--app-id", appId}, args...)
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/standalone/init_negative_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build e2e
// +build e2e
//go:build e2e && !template
// +build e2e,!template

/*
Copyright 2022 The Dapr Authors
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/standalone/init_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build e2e
// +build e2e
//go:build e2e && !template
// +build e2e,!template

/*
Copyright 2022 The Dapr Authors
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/standalone/invoke_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build e2e
// +build e2e
//go:build e2e && !template
// +build e2e,!template

/*
Copyright 2022 The Dapr Authors
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/standalone/list_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build e2e
// +build e2e
//go:build e2e && !template
// +build e2e,!template

/*
Copyright 2022 The Dapr Authors
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/standalone/publish_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build e2e
// +build e2e
//go:build e2e && !template
// +build e2e,!template

/*
Copyright 2022 The Dapr Authors
Expand Down
Loading

0 comments on commit 17dbe5b

Please sign in to comment.