Skip to content

Commit

Permalink
Integration tests (#502)
Browse files Browse the repository at this point in the history
* Use test http server for integration tests

* Delete original integration test scaffolding

* Add integration tests to GHA and split tests into separate jobs

* Remove e2e test. It doesn't do anything

* Don't publish pact from branches
  • Loading branch information
divolgin authored Jan 27, 2025
1 parent f9992ff commit ac15738
Show file tree
Hide file tree
Showing 14 changed files with 276 additions and 242 deletions.
39 changes: 31 additions & 8 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,47 @@ on:
- main

jobs:
make-tests:
env:
PACT_VERSION: ${{ github.sha }}
PACT_BROKER_BASE_URL: ${{ secrets.PACT_BROKER_BASE_URL }}
PACT_BROKER_TOKEN: ${{ secrets.PACT_BROKER_TOKEN }}
make-unit-tests:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: '^1.22'
- run: make test-unit

make-pact-tests:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: '^1.22'
- uses: replicatedhq/action-install-pact@v1
- run: make test
- if: github.event_name == 'push' || ( github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository )
- name: setup pact environment
run: |
if [[ $GITHUB_REF_NAME == 'main' ]]; then
echo "Adding pact environment variables"
echo "PACT_VERSION=${{ github.sha }}" >> "$GITHUB_ENV"
echo "PACT_BROKER_BASE_URL=${{ secrets.PACT_BROKER_BASE_URL }}" >> "$GITHUB_ENV"
echo "PACT_BROKER_TOKEN=${{ secrets.PACT_BROKER_TOKEN }}" >> "$GITHUB_ENV"
fi
- run: make test-pact
- if: github.ref == 'refs/heads/main' && ( github.event_name == 'push' || ( github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository ) )
run: make publish-pact
- if: github.event_name == 'push' || ( github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository )
- if: github.ref == 'refs/heads/main' && ( github.event_name == 'push' || ( github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository ) )
run: |
make can-i-deploy || echo "::warning:: can-i-deploy says no; provider(s) must successfully verify before release"
make-integration-tests:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: '^1.22'
- run: make test-integration

make-build:
runs-on: ubuntu-20.04
steps:
Expand Down
32 changes: 0 additions & 32 deletions .github/workflows/working.yml

This file was deleted.

11 changes: 0 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,6 @@ test-pact:
test-integration: build
go test -v ./pkg/integration/...

.PNONY: test-e2e
test-e2e:
# integration and e2e
docker build -t replicated-cli-test -f hack/Dockerfile.testing .
docker run --rm --name replicated-cli-tests \
-v `pwd`:/go/src/github.com/replicatedhq/replicated \
replicated-cli-test

.PHONY: test
test: test-unit test-pact test-e2e

.PHONY: publish-pact
publish-pact:
pact-broker publish ./pacts \
Expand Down
7 changes: 0 additions & 7 deletions cli/cmd/app_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (

"github.com/pkg/errors"
"github.com/replicatedhq/replicated/cli/print"
"github.com/replicatedhq/replicated/pkg/integration"
"github.com/replicatedhq/replicated/pkg/kotsclient"
"github.com/replicatedhq/replicated/pkg/types"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -40,12 +39,6 @@ replicated app create "Custom App" --output table`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
ctx := context.Background()
if integrationTest != "" {
ctx = context.WithValue(ctx, integration.IntegrationTestContextKey, integrationTest)
}
if logAPICalls != "" {
ctx = context.WithValue(ctx, integration.APICallLogContextKey, logAPICalls)
}

if len(args) != 1 {
return errors.New("missing app name")
Expand Down
8 changes: 0 additions & 8 deletions cli/cmd/app_ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (

"github.com/pkg/errors"
"github.com/replicatedhq/replicated/cli/print"
"github.com/replicatedhq/replicated/pkg/integration"
"github.com/replicatedhq/replicated/pkg/types"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -40,13 +39,6 @@ replicated app ls --output json
replicated app ls "App Name" --output table`,
RunE: func(cmd *cobra.Command, args []string) error {
ctx := context.Background()
if integrationTest != "" {
ctx = context.WithValue(ctx, integration.IntegrationTestContextKey, integrationTest)
}
if logAPICalls != "" {
ctx = context.WithValue(ctx, integration.APICallLogContextKey, logAPICalls)
}

return r.listApps(ctx, cmd, args, outputFormat)
},
SilenceUsage: true,
Expand Down
8 changes: 0 additions & 8 deletions cli/cmd/app_rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"github.com/manifoldco/promptui"
"github.com/pkg/errors"
"github.com/replicatedhq/replicated/cli/print"
"github.com/replicatedhq/replicated/pkg/integration"
"github.com/replicatedhq/replicated/pkg/logger"
"github.com/replicatedhq/replicated/pkg/types"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -40,13 +39,6 @@ replicated app delete "Another App" --force
replicated app delete "Custom App" --output json`,
RunE: func(cmd *cobra.Command, args []string) error {
ctx := context.Background()
if integrationTest != "" {
ctx = context.WithValue(ctx, integration.IntegrationTestContextKey, integrationTest)
}
if logAPICalls != "" {
ctx = context.WithValue(ctx, integration.APICallLogContextKey, logAPICalls)
}

if len(args) != 1 {
return errors.New("missing app slug or id")
}
Expand Down
8 changes: 0 additions & 8 deletions cli/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ const (

var appSlugOrID string
var apiToken string
var integrationTest string
var logAPICalls string
var platformOrigin = "https://api.replicated.com/vendor"
var kurlDotSHOrigin = "https://kurl.sh"
var cache *replicatedcache.Cache
Expand Down Expand Up @@ -59,12 +57,6 @@ func GetRootCmd() *cobra.Command {
rootCmd.PersistentFlags().StringVar(&appSlugOrID, "app", "", "The app slug or app id to use in all calls")
rootCmd.PersistentFlags().StringVar(&apiToken, "token", "", "The API token to use to access your app in the Vendor API")

rootCmd.PersistentFlags().StringVar(&integrationTest, "integration-test", "", "Set to the name of the integration test to run")
rootCmd.Flags().MarkHidden("integration-test")

rootCmd.PersistentFlags().StringVar(&logAPICalls, "log-api-calls", "", "Log the API calls to the specified file")
rootCmd.Flags().MarkHidden("log-api-calls")

return rootCmd
}

Expand Down
6 changes: 0 additions & 6 deletions hack/Dockerfile.testing

This file was deleted.

138 changes: 138 additions & 0 deletions pkg/integration/api_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package integration

import (
"io"
"net/http"
"net/http/httptest"
"os/exec"
"testing"

"github.com/gorilla/mux"
"github.com/stretchr/testify/assert"
)

func TestAPI(t *testing.T) {
tests := []struct {
name string
cliArgs []string
getCommand func([]string, *httptest.Server) *exec.Cmd
getServer func(t *testing.T) *httptest.Server
wantFormat format
wantLines int
wantError string
}{
{
name: "api get",
cliArgs: []string{"api", "get", "/v3/some/path"},
getCommand: getCommand,
getServer: func(t *testing.T) *httptest.Server {
r := mux.NewRouter()

r.Methods(http.MethodGet).Path("/v3/some/path").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
auth := r.Header.Get("Authorization")
assert.Equal(t, auth, "test-token")

w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"test-key": "test-value"}`))
})

return httptest.NewServer(r)
},
wantFormat: FormatJSON,
},
{
name: "api patch",
cliArgs: []string{"api", "patch", "/v3/some/path", "-b", `{"test-key": "test-value"}`},
getCommand: getCommand,
getServer: func(t *testing.T) *httptest.Server {
r := mux.NewRouter()
r.Methods(http.MethodPatch).Path("/v3/some/path").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
auth := r.Header.Get("Authorization")
assert.Equal(t, auth, "test-token")

body, err := io.ReadAll(r.Body)
assert.NoError(t, err)
assert.Equal(t, string(body), `{"test-key": "test-value"}`)

w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"test-key": "test-value"}`))
})
return httptest.NewServer(r)
},
wantFormat: FormatJSON,
},
{
name: "api post",
cliArgs: []string{"api", "post", "/v3/some/path", "-b", `{"test-key": "test-value"}`},
getCommand: getCommand,
getServer: func(t *testing.T) *httptest.Server {
r := mux.NewRouter()
r.Methods(http.MethodPost).Path("/v3/some/path").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
auth := r.Header.Get("Authorization")
assert.Equal(t, auth, "test-token")

body, err := io.ReadAll(r.Body)
assert.NoError(t, err)
assert.Equal(t, string(body), `{"test-key": "test-value"}`)

w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"test-key": "test-value"}`))
})
return httptest.NewServer(r)
},
wantFormat: FormatJSON,
},
{
name: "api put",
cliArgs: []string{"api", "put", "/v3/some/path", "-b", `{"test-key": "test-value"}`},
getCommand: getCommand,
getServer: func(t *testing.T) *httptest.Server {
r := mux.NewRouter()
r.Methods(http.MethodPut).Path("/v3/some/path").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
auth := r.Header.Get("Authorization")
assert.Equal(t, auth, "test-token")

body, err := io.ReadAll(r.Body)
assert.NoError(t, err)
assert.Equal(t, string(body), `{"test-key": "test-value"}`)

w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"test-key": "test-value"}`))
})
return httptest.NewServer(r)
},
wantFormat: FormatJSON,
},
{
name: "api get missing api token",
cliArgs: []string{"api", "get", "/v3/some/path"},
getCommand: getCommandWithoutToken,
getServer: func(t *testing.T) *httptest.Server {
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusUnauthorized)
}))
},
wantFormat: FormatTable,
wantLines: 1,
wantError: "token or log in",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
server := tt.getServer(t)
defer server.Close()

cmd := tt.getCommand(tt.cliArgs, server)
out, err := cmd.CombinedOutput()

if tt.wantError != "" {
assert.Contains(t, string(out), tt.wantError)
} else {
assert.NoError(t, err)
}

AssertCLIOutput(t, string(out), tt.wantFormat, tt.wantLines)
})
}
}
Loading

0 comments on commit ac15738

Please sign in to comment.