Skip to content

Commit

Permalink
test: added e2e-test
Browse files Browse the repository at this point in the history
  • Loading branch information
ReuDa committed Sep 14, 2023
1 parent d38a6c7 commit b92bfa3
Show file tree
Hide file tree
Showing 12 changed files with 309 additions and 44 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ extension-postman
*.iml
/vendor
coverage.out
/e2e/e2e-coverage-docker.out
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ FROM golang:1.20-alpine AS build
ARG NAME
ARG VERSION
ARG REVISION
ARG ADDITIONAL_BUILD_PARAMS

WORKDIR /app

Expand All @@ -22,7 +23,8 @@ RUN go build \
-X 'github.com/steadybit/extension-kit/extbuild.ExtensionName=${NAME}' \
-X 'github.com/steadybit/extension-kit/extbuild.Version=${VERSION}' \
-X 'github.com/steadybit/extension-kit/extbuild.Revision=${REVISION}'" \
-o ./extension
-o ./extension \
${ADDITIONAL_BUILD_PARAMS}

##
## Runtime
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@ run: tidy build
## container: build the container image
.PHONY: container
container:
docker build -t extension-postman:latest .
docker build --build-arg ADDITIONAL_BUILD_PARAMS="-cover" -t extension-postman:latest .
20 changes: 20 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2022 Steadybit GmbH

package config

import (
"github.com/kelseyhightower/envconfig"
"github.com/rs/zerolog/log"
)

var (
Config Specification
)

func ParseConfiguration() {
err := envconfig.Process("steadybit_extension", &Config)
if err != nil {
log.Fatal().Err(err).Msgf("Failed to parse configuration from environment.")
}
}
8 changes: 8 additions & 0 deletions config/specification.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2022 Steadybit GmbH

package config

type Specification struct {
PostmanBaseUrl string `json:"postmanBaseUrl" split_words:"true" required:"false" default:"https://api.getpostman.com"`
}
57 changes: 57 additions & 0 deletions e2e/integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2023 Steadybit GmbH

package e2e

import (
"fmt"
"github.com/steadybit/action-kit/go/action_kit_test/e2e"
"github.com/steadybit/extension-kit/extlogging"
"github.com/stretchr/testify/require"
"strings"
"testing"
"time"
)

func TestWithMinikube(t *testing.T) {
extlogging.InitZeroLog()
server := createMockPostmanServer()
defer server.Close()
split := strings.SplitAfter(server.URL, ":")
port := split[len(split)-1]

extFactory := e2e.HelmExtensionFactory{
Name: "extension-postman",
Port: 8086,
ExtraArgs: func(m *e2e.Minikube) []string {
return []string{
"--set", "logging.level=debug",
"--set", "extraEnv[0].name=STEADYBIT_EXTENSION_POSTMAN_BASE_URL",
"--set", fmt.Sprintf("extraEnv[0].value=%s:%s", "http://host.minikube.internal:", port),
}
},
}

e2e.WithDefaultMinikube(t, &extFactory, []e2e.WithMinikubeTestCase{
{
Name: "run postman",
Test: testRunPostman,
},
})
}

func testRunPostman(t *testing.T, m *e2e.Minikube, e *e2e.Extension) {
config := struct {
CollectionId string
ApiKey string
}{
CollectionId: "testCollectionId",
ApiKey: "testApiKey",
}

exec, err := e.RunAction("com.steadybit.extension_postman.collection.run", nil, config, nil)
require.NoError(t, err)
e2e.AssertLogContainsWithTimeout(t, m, e.Pod, "Starting newman!", 90*time.Second)
e2e.AssertLogContainsWithTimeout(t, m, e.Pod, "Postman run completed successfully", 90*time.Second)
require.NoError(t, exec.Cancel())
}
37 changes: 37 additions & 0 deletions e2e/mock_postman_server_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package e2e

import (
"fmt"
"github.com/rs/zerolog/log"
"net"
"net/http"
"net/http/httptest"
"strings"
)

func createMockPostmanServer() *httptest.Server {
listener, err := net.Listen("tcp", "0.0.0.0:0")
if err != nil {
panic(fmt.Sprintf("httptest: failed to listen: %v", err))
}
server := httptest.Server{
Listener: listener,
Config: &http.Server{Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Info().Str("path", r.URL.Path).Str("method", r.Method).Str("query", r.URL.RawQuery).Msg("Request received")
if strings.Contains(r.URL.Path, "collections/testCollectionId") {
w.WriteHeader(http.StatusOK)
w.Write(getCollection())
} else {
w.WriteHeader(http.StatusBadRequest)
}
})},
}
server.Start()
log.Info().Str("url", server.URL).Msg("Started Mock-Server")
return &server
}

func getCollection() []byte {
log.Info().Msg("Return collection")
return []byte(`{"collection":{"info":{"_postman_id":"1c89f353-9e9d-4daf-9442-bc64f4c1b29b","name":"Simple Get","schema":"https://schema.getpostman.com/json/collection/v2.1.0/collection.json","updatedAt":"2023-09-14T11:22:30.000Z","uid":"21222108-1c89f353-9e9d-4daf-9442-bc64f4c1b29b"},"item":[{"name":"Is google online","event":[{"listen":"test","script":{"id":"13df8fb5-f68d-4822-93b4-a6a67c512420","exec":["pm.test(\"Body matches string\", function () {"," pm.expect(pm.response.text()).to.include(\"Google\");","});"],"type":"text/javascript"}}],"id":"fd6c6e49-dbf2-4f21-92ef-c0a2bf10b426","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":{"raw":"https://www.google.de","protocol":"https","host":["www","google","de"]}},"response":[],"uid":"21222108-fd6c6e49-dbf2-4f21-92ef-c0a2bf10b426"}]}}`)
}
40 changes: 21 additions & 19 deletions extpostman/action_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/steadybit/extension-kit/extconversion"
"github.com/steadybit/extension-kit/extfile"
"github.com/steadybit/extension-kit/extutil"
"github.com/steadybit/extension-postman/config"
"os"
"os/exec"
"strings"
Expand Down Expand Up @@ -154,41 +155,42 @@ func (f PostmanAction) Describe() action_kit_api.ActionDescription {
}
}

func (f PostmanAction) Prepare(_ context.Context, state *PostmanState, request action_kit_api.PrepareActionRequestBody) (*action_kit_api.PrepareResult, error) {
var config PostmanConfig
if err := extconversion.Convert(request.Config, &config); err != nil {
func (f PostmanAction) Prepare(_ context.Context, state *PostmanState, raw action_kit_api.PrepareActionRequestBody) (*action_kit_api.PrepareResult, error) {
var request PostmanConfig
if err := extconversion.Convert(raw.Config, &request); err != nil {
return nil, extension_kit.ToError("Failed to unmarshal the config.", err)
}
config := config.Config

state.Timestamp = time.Now().Format(time.RFC3339)
state.Command = []string{
"newman",
"run",
fmt.Sprintf("https://api.getpostman.com/collections/%s?apikey=%s", config.CollectionId, config.ApiKey),
fmt.Sprintf("%s/collections/%s?apikey=%s", config.PostmanBaseUrl, request.CollectionId, request.ApiKey),
}
if config.EnvironmentId != "" {
if request.EnvironmentId != "" {
state.Command = append(state.Command, "--environment")
state.Command = append(state.Command, fmt.Sprintf("https://api.getpostman.com/environments/%s?apikey=%s", config.EnvironmentId, config.ApiKey))
state.Command = append(state.Command, fmt.Sprintf("%s/environments/%s?apikey=%s", config.PostmanBaseUrl, request.EnvironmentId, request.ApiKey))
}
if config.Environment != nil {
for _, value := range config.Environment {
if request.Environment != nil {
for _, value := range request.Environment {
state.Command = append(state.Command, "--env-var")
state.Command = append(state.Command, fmt.Sprintf("%s=%s", value["key"], value["value"]))
}
}
if config.Verbose {
if request.Verbose {
state.Command = append(state.Command, "--verbose")
}
if config.Bail {
if request.Bail {
state.Command = append(state.Command, "--bail")
}
if config.Timeout > 0 {
if request.Timeout > 0 {
state.Command = append(state.Command, "--timeout")
state.Command = append(state.Command, fmt.Sprintf("%d", config.Timeout))
state.Command = append(state.Command, fmt.Sprintf("%d", request.Timeout))
}
if config.TimeoutRequest > 0 {
if request.TimeoutRequest > 0 {
state.Command = append(state.Command, "--timeout-request")
state.Command = append(state.Command, fmt.Sprintf("%d", config.TimeoutRequest))
state.Command = append(state.Command, fmt.Sprintf("%d", request.TimeoutRequest))
}

state.Command = append(state.Command, "--reporters")
Expand All @@ -199,11 +201,11 @@ func (f PostmanAction) Prepare(_ context.Context, state *PostmanState, request a
state.Command = append(state.Command, fmt.Sprintf("/tmp/newman-result_%s.html", state.Timestamp))
state.Command = append(state.Command, "--reporter-htmlextra-omitResponseBodies")

if config.Iterations > 1 {
if request.Iterations > 1 {
state.Command = append(state.Command, "-n")
state.Command = append(state.Command, fmt.Sprintf("%d", config.Iterations))
state.Command = append(state.Command, fmt.Sprintf("%d", request.Iterations))
}
log.Info().Msgf("Prepared action. Command: %s", extutil.MaskString(strings.Join(state.Command, " "), config.ApiKey, 4))
log.Info().Msgf("Prepared action. Command: %s", extutil.MaskString(strings.Join(state.Command, " "), request.ApiKey, 4))
return nil, nil
}

Expand Down Expand Up @@ -288,7 +290,7 @@ func (f PostmanAction) Status(_ context.Context, state *PostmanState) (*action_k
}

func getStdOutMessages(lines []string) []action_kit_api.Message {
var messages []action_kit_api.Message
messages := make([]action_kit_api.Message, 0)
for _, line := range lines {
messages = append(messages, action_kit_api.Message{
Level: extutil.Ptr(action_kit_api.Info),
Expand Down Expand Up @@ -329,7 +331,7 @@ func (f PostmanAction) Stop(_ context.Context, state *PostmanState) (*action_kit
var summaryFileContent string
var htmlResultFileContent string

var artifacts []action_kit_api.Artifact
artifacts := make([]action_kit_api.Artifact, 0)

// check if summary file exists and send it as artifact
const ResultSummaryFileName = "/tmp/newman-result-summary_%s.json"
Expand Down
45 changes: 38 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ module github.com/steadybit/extension-postman
go 1.20

require (
github.com/kelseyhightower/envconfig v1.4.0
github.com/rs/zerolog v1.30.0
github.com/steadybit/action-kit/go/action_kit_api/v2 v2.7.2
github.com/steadybit/action-kit/go/action_kit_sdk v1.1.6
github.com/steadybit/action-kit/go/action_kit_sdk v1.1.7
github.com/steadybit/action-kit/go/action_kit_test v1.2.0
github.com/steadybit/extension-kit v1.8.8
github.com/stretchr/testify v1.8.4
)
Expand All @@ -19,38 +21,47 @@ require (
github.com/andybalholm/brotli v1.0.5 // indirect
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
github.com/bytedance/sonic v1.10.0 // indirect
github.com/bytedance/sonic v1.10.1 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
github.com/chenzhuoyu/iasm v0.9.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/deepmap/oapi-codegen v1.14.0 // indirect
github.com/deepmap/oapi-codegen v1.15.0 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/flosch/pongo2/v4 v4.0.2 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/getkin/kin-openapi v0.120.0 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/gin-gonic/gin v1.9.1 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-openapi/jsonpointer v0.20.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.4 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.15.3 // indirect
github.com/go-playground/validator/v10 v10.15.4 // indirect
github.com/go-resty/resty/v2 v2.7.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/gomarkdown/markdown v0.0.0-20230716120725-531d2d74bc12 // indirect
github.com/gomarkdown/markdown v0.0.0-20230912175223-14b07df9d538 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/invopop/yaml v0.2.0 // indirect
github.com/iris-contrib/schema v0.0.6 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kataras/blocks v0.0.7 // indirect
github.com/kataras/golog v0.1.9 // indirect
github.com/kataras/iris/v12 v12.2.5 // indirect
github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9 // indirect
github.com/kataras/pio v0.0.12 // indirect
github.com/kataras/sitemap v0.0.6 // indirect
github.com/kataras/tunnel v0.0.4 // indirect
github.com/kelseyhightower/envconfig v1.4.0 // indirect
github.com/klauspost/compress v1.16.7 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/labstack/echo/v4 v4.11.1 // indirect
Expand All @@ -61,16 +72,21 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/microcosm-cc/bluemonday v1.0.25 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/perimeterx/marshmallow v1.1.5 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rs/xid v1.5.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/schollz/closestmatch v2.1.0+incompatible // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/steadybit/discovery-kit/go/discovery_kit_api v1.4.2 // indirect
github.com/steadybit/discovery-kit/go/discovery_kit_test v1.0.2 // indirect
github.com/tdewolff/minify/v2 v2.12.9 // indirect
github.com/tdewolff/parse/v2 v2.6.8 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
Expand All @@ -79,14 +95,29 @@ require (
github.com/valyala/fasttemplate v1.2.2 // indirect
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect
github.com/yosssi/ace v0.0.5 // indirect
golang.org/x/arch v0.5.0 // indirect
golang.org/x/crypto v0.13.0 // indirect
golang.org/x/net v0.15.0 // indirect
golang.org/x/oauth2 v0.12.0 // indirect
golang.org/x/sys v0.12.0 // indirect
golang.org/x/term v0.12.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/time v0.3.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.29.0-alpha.0 // indirect
k8s.io/apimachinery v0.29.0-alpha.0 // indirect
k8s.io/client-go v0.29.0-alpha.0 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/kube-openapi v0.0.0-20230905202853-d090da108d2f // indirect
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)
Loading

0 comments on commit b92bfa3

Please sign in to comment.