Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update integration tests for other app commands #456

Merged
merged 2 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions cli/cmd/app_create.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package cmd

import (
"context"

"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 @@ -35,11 +38,19 @@ The NAME argument is required and will be used as the application's name.`,
# Create a new app with a specific name and view details in table format
replicated app create "Custom App" --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)
}

if len(args) != 1 {
return errors.New("missing app name")
}
opts.name = args[0]
return r.createApp(cmd, opts, outputFormat)
return r.createApp(ctx, cmd, opts, outputFormat)
},
SilenceUsage: true,
}
Expand All @@ -49,10 +60,12 @@ The NAME argument is required and will be used as the application's name.`,
return cmd
}

func (r *runners) createApp(cmd *cobra.Command, opts createAppOpts, outputFormat string) error {
kotsRestClient := kotsclient.VendorV3Client{HTTPClient: *r.platformAPI}
func (r *runners) createApp(ctx context.Context, cmd *cobra.Command, opts createAppOpts, outputFormat string) error {
kotsRestClient := kotsclient.VendorV3Client{
HTTPClient: *r.platformAPI,
}

app, err := kotsRestClient.CreateKOTSApp(opts.name)
app, err := kotsRestClient.CreateKOTSApp(ctx, opts.name)
if err != nil {
return errors.Wrap(err, "create app")
}
Expand Down
26 changes: 20 additions & 6 deletions cli/cmd/app_rm.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package cmd

import (
"context"

"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 @@ -36,10 +39,18 @@ Use this command with caution as there is no way to undo this operation.`,
# Delete an app and output the result in JSON format
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")
}
return r.deleteApp(cmd, args[0], opts, outputFormat)
return r.deleteApp(ctx, cmd, args[0], opts, outputFormat)
},
SilenceUsage: true,
}
Expand All @@ -50,18 +61,22 @@ Use this command with caution as there is no way to undo this operation.`,
return cmd
}

func (r *runners) deleteApp(cmd *cobra.Command, appName string, opts deleteAppOpts, outputFormat string) error {
func (r *runners) deleteApp(ctx context.Context, cmd *cobra.Command, appName string, opts deleteAppOpts, outputFormat string) error {
log := logger.NewLogger(r.w)

log.ActionWithSpinner("Fetching App")
app, err := r.kotsAPI.GetApp(appName, true)
app, err := r.kotsAPI.GetApp(ctx, appName, true)
if err != nil {
log.FinishSpinnerWithError()
return errors.Wrap(err, "list apps")
}
log.FinishSpinner()

apps := []types.AppAndChannels{{App: app}}
apps := []types.AppAndChannels{
{
App: app,
},
}

err = print.Apps(outputFormat, r.w, apps)
if err != nil {
Expand All @@ -80,7 +95,7 @@ func (r *runners) deleteApp(cmd *cobra.Command, appName string, opts deleteAppOp
}

log.ActionWithSpinner("Deleting App")
err = r.kotsAPI.DeleteKOTSApp(app.ID)
err = r.kotsAPI.DeleteKOTSApp(ctx, app.ID)
if err != nil {
log.FinishSpinnerWithError()
return errors.Wrap(err, "delete app")
Expand All @@ -98,7 +113,6 @@ var templates = &promptui.PromptTemplates{
}

func promptConfirmDelete() (string, error) {

prompt := promptui.Prompt{
Label: "Delete the above listed application? There is no undo:",
Templates: templates,
Expand Down
4 changes: 3 additions & 1 deletion cli/cmd/cache_helper.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cmd

import (
"context"

"github.com/pkg/errors"
"github.com/replicatedhq/replicated/pkg/kotsclient"
"github.com/replicatedhq/replicated/pkg/types"
Expand All @@ -17,7 +19,7 @@ func getApp(appSlugOrID string, kotsClient *kotsclient.VendorV3Client) (*types.A
}

if app == nil {
a, err := kotsClient.GetApp(appSlugOrID, true)
a, err := kotsClient.GetApp(context.TODO(), appSlugOrID, true)
if err != nil {
return nil, errors.Wrap(err, "get app from api")
}
Expand Down
3 changes: 2 additions & 1 deletion cli/cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"context"
"fmt"
"io"
"os"
Expand Down Expand Up @@ -348,7 +349,7 @@ func Execute(rootCmd *cobra.Command, stdin io.Reader, stdout io.Writer, stderr i
}

if appSlugOrID != "" && (runCmds.appType == "" || runCmds.appID == "" || runCmds.appSlug == "") {
app, appType, err := runCmds.api.GetAppType(appSlugOrID, true)
app, appType, err := runCmds.api.GetAppType(context.TODO(), appSlugOrID, true)
if err != nil {
return errors.Wrap(err, "get app type")
}
Expand Down
6 changes: 4 additions & 2 deletions client/client.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package client

import (
"context"

"github.com/pkg/errors"
"github.com/replicatedhq/replicated/pkg/kotsclient"
"github.com/replicatedhq/replicated/pkg/platformclient"
Expand All @@ -22,7 +24,7 @@ func NewClient(platformOrigin string, apiToken string, kurlOrigin string) Client
return client
}

func (c *Client) GetAppType(appID string, excludeChannels bool) (*types.App, string, error) {
func (c *Client) GetAppType(ctx context.Context, appID string, excludeChannels bool) (*types.App, string, error) {
platformSwaggerApp, err1 := c.PlatformClient.GetApp(appID)
if err1 == nil && platformSwaggerApp != nil {
platformApp := &types.App{
Expand All @@ -34,7 +36,7 @@ func (c *Client) GetAppType(appID string, excludeChannels bool) (*types.App, str
return platformApp, "platform", nil
}

kotsApp, err2 := c.KotsClient.GetApp(appID, excludeChannels)
kotsApp, err2 := c.KotsClient.GetApp(ctx, appID, excludeChannels)
if err2 == nil && kotsApp != nil {
return kotsApp, "kots", nil
}
Expand Down
3 changes: 2 additions & 1 deletion pact/kotsclient/app_create_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package kotsclient

import (
"context"
"fmt"
"testing"

Expand All @@ -17,7 +18,7 @@ func Test_AppCreate(t *testing.T) {
api := platformclient.NewHTTPClient(u, "replicated-cli-app-create-token")
client := realkotsclient.VendorV3Client{HTTPClient: *api}

createdApp, err := client.CreateKOTSApp("app-create-1")
createdApp, err := client.CreateKOTSApp(context.TODO(), "app-create-1")
assert.Nil(t, err)

assert.Equal(t, "app-create-1", createdApp.Name)
Expand Down
2 changes: 1 addition & 1 deletion pact/kotsclient/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func Test_RemoveApp(t *testing.T) {
api := platformclient.NewHTTPClient(u, "replicated-cli-rm-app-token")
client := realkotsclient.VendorV3Client{HTTPClient: *api}

err = client.DeleteKOTSApp("replicated-cli-rm-app-app")
err = client.DeleteKOTSApp(context.TODO(), "replicated-cli-rm-app-app")
assert.Nil(t, err)

apps, err := client.ListApps(context.TODO(), false)
Expand Down
57 changes: 41 additions & 16 deletions pkg/integration/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,64 @@ import (

func TestApp(t *testing.T) {
tests := []struct {
name string
cli string
wantFormat format
wantLines int
wantMethod string
wantPath string
name string
cli string
wantFormat format
wantLines int
wantAPIRequests []string
ignoreCLIOutput bool
}{
{
name: "app-ls-empty",
cli: "app ls",
wantFormat: FormatTable,
wantLines: 1,
wantMethod: "GET",
wantPath: "/v3/apps?excludeChannels=false",
wantAPIRequests: []string{
"GET:/v3/apps?excludeChannels=false",
},
},
{
name: "app-ls-empty",
cli: "app ls --output json",
wantFormat: FormatJSON,
wantMethod: "GET",
wantPath: "/v3/apps?excludeChannels=false",
wantAPIRequests: []string{
"GET:/v3/apps?excludeChannels=false",
},
},
{
name: "app-ls-single",
cli: "app ls",
wantFormat: FormatTable,
wantLines: 2,
wantMethod: "GET",
wantPath: "/v3/apps?excludeChannels=false",
wantAPIRequests: []string{
"GET:/v3/apps?excludeChannels=false",
},
},
{
name: "app-ls-single",
cli: "app ls --output json",
wantFormat: FormatJSON,
wantMethod: "GET",
wantPath: "/v3/apps?excludeChannels=false",
wantAPIRequests: []string{
"GET:/v3/apps?excludeChannels=false",
},
},
{
name: "app-rm",
cli: "app rm slug --force",
wantAPIRequests: []string{
"GET:/v3/apps?excludeChannels=true",
"DELETE:/v3/app/id",
},
ignoreCLIOutput: true,
},
{
name: "app-create",
cli: "app create name",
wantFormat: FormatTable,
wantLines: 2,
wantAPIRequests: []string{
"POST:/v3/app",
},
},
}

Expand All @@ -69,8 +91,11 @@ func TestApp(t *testing.T) {
t.Errorf("error running cli: %v", err)
}

AssertCLIOutput(t, string(out), tt.wantFormat, tt.wantLines)
AssertAPIRequests(t, tt.wantMethod, tt.wantPath, apiCallLog.Name())
if !tt.ignoreCLIOutput {
AssertCLIOutput(t, string(out), tt.wantFormat, tt.wantLines)
}

AssertAPIRequests(t, tt.wantAPIRequests, apiCallLog.Name())
})
}
}
12 changes: 8 additions & 4 deletions pkg/integration/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ var (
Name: "channel-name",
},
},
Id: "id",
Slug: "slug",
Name: "name",
IsFoundation: true,
Expand All @@ -37,19 +38,22 @@ var (
func Response(key string) interface{} {
switch key {
case "app-ls-empty":
return kotsclienttypes.KotsAppResponse{
return &kotsclienttypes.KotsAppResponse{
Apps: []types.KotsAppWithChannels{},
}
case "app-ls-single":
return kotsclienttypes.KotsAppResponse{
case "app-ls-single", "app-rm":
return &kotsclienttypes.KotsAppResponse{
Apps: []types.KotsAppWithChannels{
typeKOTSAppWithChannels,
},
}
case "app-create":
return &kotsclienttypes.CreateKOTSAppResponse{
App: &typeKOTSAppWithChannels,
}
default:
panic(fmt.Sprintf("unknown integration test: %s", key))
}

}

func CLIPath() string {
Expand Down
27 changes: 24 additions & 3 deletions pkg/integration/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,34 @@ func AssertCLIOutput(t *testing.T, got string, wantFormat format, wantLines int)
}
}

func AssertAPIRequests(t *testing.T, wantMethod string, wantPath string, apiCallLogFilename string) {
func AssertAPIRequests(t *testing.T, wantAPIRequests []string, apiCallLogFilename string) {
apiCallLog, err := os.ReadFile(apiCallLogFilename)
if err != nil {
t.Errorf("error reading api call log: %v", err)
return
}

if string(apiCallLog) != fmt.Sprintf("%s:%s\n", wantMethod, wantPath) {
t.Errorf("got %s, want %s", apiCallLog, fmt.Sprintf("%s:%s\n", wantMethod, wantPath))
gotAPIRequests := strings.Split(string(apiCallLog), "\n")

cleaned := []string{}
for _, line := range gotAPIRequests {
if strings.TrimSpace(line) != "" {
cleaned = append(cleaned, line)
}
}
gotAPIRequests = cleaned

if len(gotAPIRequests) != len(wantAPIRequests) {
fmt.Printf("got: %v\n", gotAPIRequests)
fmt.Printf("want: %v\n", wantAPIRequests)
t.Errorf("got %d requests, want %d", len(gotAPIRequests), len(wantAPIRequests))
return
}

for i, wantAPIRequest := range wantAPIRequests {
gotAPIRequest := gotAPIRequests[i]
if gotAPIRequest != wantAPIRequest {
t.Errorf("got %s, want %s", gotAPIRequest, wantAPIRequest)
}
}
}
Loading
Loading