-
Notifications
You must be signed in to change notification settings - Fork 812
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
Add test for admin cluster commands #6397
Merged
Merged
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,9 @@ package cli | |
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"github.com/uber/cadence/client/admin" | ||
"github.com/uber/cadence/service/worker/failovermanager" | ||
"testing" | ||
|
||
"github.com/golang/mock/gomock" | ||
|
@@ -134,3 +137,348 @@ func TestValidSearchAttributeKey(t *testing.T) { | |
assert.Error(t, visibility.ValidateSearchAttributeKey("9lives")) | ||
assert.Error(t, visibility.ValidateSearchAttributeKey("tax%")) | ||
} | ||
|
||
func TestAdminDescribeCluster(t *testing.T) { | ||
// Initialize mock controller | ||
mockCtrl := gomock.NewController(t) | ||
defer mockCtrl.Finish() | ||
|
||
// Create mock frontend and admin clients | ||
serverFrontendClient := frontend.NewMockClient(mockCtrl) | ||
serverAdminClient := admin.NewMockClient(mockCtrl) | ||
Comment on lines
+147
to
+148
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's avoid defining mocks at top level like this. If one test case's expectation fails it will fail the rest. better to define these inside inner t.Run for isolation purposes |
||
|
||
// Set up the CLI app and mock dependencies | ||
app := NewCliApp(&clientFactoryMock{ | ||
serverFrontendClient: serverFrontendClient, | ||
serverAdminClient: serverAdminClient, | ||
}) | ||
|
||
tests := []struct { | ||
name string | ||
mockSetup func() | ||
expectedError string | ||
}{ | ||
{ | ||
name: "Success", | ||
mockSetup: func() { | ||
// Expected response from DescribeCluster | ||
expectedResponse := &types.DescribeClusterResponse{ | ||
SupportedClientVersions: &types.SupportedClientVersions{ | ||
GoSdk: "1.5.0", | ||
}, | ||
} | ||
// Mock the DescribeCluster call | ||
serverAdminClient.EXPECT().DescribeCluster(gomock.Any()).Return(expectedResponse, nil).Times(1) | ||
}, | ||
expectedError: "", | ||
}, | ||
{ | ||
name: "DescribeClusterError", | ||
mockSetup: func() { | ||
// Mock DescribeCluster to return an error | ||
serverAdminClient.EXPECT().DescribeCluster(gomock.Any()).Return(nil, fmt.Errorf("DescribeCluster failed")).Times(1) | ||
}, | ||
expectedError: "Operation DescribeCluster failed.", | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
// Set up mock based on the specific test case | ||
tt.mockSetup() | ||
|
||
// Set up CLI context | ||
set := flag.NewFlagSet("test", 0) | ||
c := cli.NewContext(app, set, nil) | ||
|
||
// Call AdminDescribeCluster | ||
err := AdminDescribeCluster(c) | ||
|
||
// Check the result based on the expected outcome | ||
if tt.expectedError != "" { | ||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), tt.expectedError) | ||
} else { | ||
assert.NoError(t, err) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestAdminRebalanceStart(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
mockSetup func(mockFrontClient *frontend.MockClient, mockClientFactory *MockClientFactory) | ||
expectedError string | ||
}{ | ||
{ | ||
name: "Success", | ||
mockSetup: func(mockFrontClient *frontend.MockClient, mockClientFactory *MockClientFactory) { | ||
// Mock StartWorkflowExecution response | ||
mockResponse := &types.StartWorkflowExecutionResponse{ | ||
RunID: "test-run-id", | ||
} | ||
mockClientFactory.EXPECT().ServerFrontendClient(gomock.Any()).Return(mockFrontClient, nil).Times(1) | ||
mockFrontClient.EXPECT().StartWorkflowExecution(gomock.Any(), gomock.Any()).Return(mockResponse, nil).Times(1) | ||
}, | ||
expectedError: "", | ||
}, | ||
{ | ||
name: "ServerFrontendClientError", | ||
mockSetup: func(mockFrontClient *frontend.MockClient, mockClientFactory *MockClientFactory) { | ||
// Mock ServerFrontendClient to return an error | ||
mockClientFactory.EXPECT().ServerFrontendClient(gomock.Any()).Return(nil, fmt.Errorf("failed to get frontend client")).Times(1) | ||
}, | ||
expectedError: "failed to get frontend client", | ||
}, | ||
{ | ||
name: "StartWorkflowExecutionError", | ||
mockSetup: func(mockFrontClient *frontend.MockClient, mockClientFactory *MockClientFactory) { | ||
// Mock StartWorkflowExecution to return an error | ||
mockClientFactory.EXPECT().ServerFrontendClient(gomock.Any()).Return(mockFrontClient, nil).Times(1) | ||
mockFrontClient.EXPECT().StartWorkflowExecution(gomock.Any(), gomock.Any()).Return(nil, fmt.Errorf("failed to start workflow")).Times(1) | ||
}, | ||
expectedError: "Failed to start failover workflow", | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
// Initialize mock controller | ||
mockCtrl := gomock.NewController(t) | ||
defer mockCtrl.Finish() | ||
|
||
// Create mock Cadence client and client factory | ||
mockFrontClient := frontend.NewMockClient(mockCtrl) | ||
mockClientFactory := NewMockClientFactory(mockCtrl) | ||
|
||
// Set up the CLI app | ||
app := cli.NewApp() | ||
app.Metadata = map[string]interface{}{ | ||
"deps": &deps{ | ||
ClientFactory: mockClientFactory, | ||
}, | ||
} | ||
|
||
// Set up the mocks for the specific test case | ||
tt.mockSetup(mockFrontClient, mockClientFactory) | ||
|
||
// Use setContextMock to set the CLI context | ||
c := setContextMock(app) | ||
|
||
// Call AdminRebalanceStart | ||
err := AdminRebalanceStart(c) | ||
|
||
// Check the result based on the expected outcome | ||
if tt.expectedError != "" { | ||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), tt.expectedError) | ||
} else { | ||
assert.NoError(t, err) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
// Helper function to set up the CLI context for AdminRebalanceStart | ||
func setContextMock(app *cli.App) *cli.Context { | ||
set := flag.NewFlagSet("test", 0) | ||
// You can add any flags relevant to AdminRebalanceStart here | ||
set.String(FlagDomain, "test-domain", "Domain flag") | ||
|
||
c := cli.NewContext(app, set, nil) | ||
return c | ||
} | ||
|
||
func TestIntValTypeToString(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
valType int | ||
expected string | ||
}{ | ||
{ | ||
name: "StringType", | ||
valType: 0, | ||
expected: "String", | ||
}, | ||
{ | ||
name: "KeywordType", | ||
valType: 1, | ||
expected: "Keyword", | ||
}, | ||
{ | ||
name: "IntType", | ||
valType: 2, | ||
expected: "Int", | ||
}, | ||
{ | ||
name: "DoubleType", | ||
valType: 3, | ||
expected: "Double", | ||
}, | ||
{ | ||
name: "BoolType", | ||
valType: 4, | ||
expected: "Bool", | ||
}, | ||
{ | ||
name: "DatetimeType", | ||
valType: 5, | ||
expected: "Datetime", | ||
}, | ||
{ | ||
name: "UnknownType", | ||
valType: 999, | ||
expected: "", | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
// Call the function and check the result | ||
result := intValTypeToString(tt.valType) | ||
assert.Equal(t, tt.expected, result) | ||
}) | ||
} | ||
} | ||
|
||
func TestAdminRebalanceList(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
prepareEnv func() *cli.Context | ||
expectedError string | ||
}{ | ||
{ | ||
name: "Success", | ||
prepareEnv: func() *cli.Context { | ||
// Initialize the mock client factory and frontend client | ||
mockFrontClient := frontend.NewMockClient(gomock.NewController(t)) | ||
mockClientFactory := NewMockClientFactory(gomock.NewController(t)) | ||
|
||
// Mock successful ListWorkflow call | ||
mockClientFactory.EXPECT().ServerFrontendClient(gomock.Any()).Return(mockFrontClient, nil).Times(1) | ||
mockFrontClient.EXPECT().CountWorkflowExecutions(gomock.Any(), gomock.Any()).Return(&types.CountWorkflowExecutionsResponse{}, nil).Times(1) | ||
mockFrontClient.EXPECT().ListClosedWorkflowExecutions(gomock.Any(), gomock.Any()).Return(&types.ListClosedWorkflowExecutionsResponse{}, nil).Times(1) | ||
|
||
// Create CLI app and set up flag set | ||
app := cli.NewApp() | ||
app.Metadata = map[string]interface{}{ | ||
"deps": &deps{ | ||
ClientFactory: mockClientFactory, | ||
}, | ||
} | ||
set := flag.NewFlagSet("test", 0) | ||
set.String(FlagWorkflowID, "", "workflow ID flag") | ||
set.String(FlagDomain, "", "domain flag") | ||
c := cli.NewContext(app, set, nil) | ||
|
||
// Set flags for workflow ID and domain | ||
_ = c.Set(FlagWorkflowID, failovermanager.RebalanceWorkflowID) | ||
_ = c.Set(FlagDomain, common.SystemLocalDomainName) | ||
|
||
return c | ||
}, | ||
expectedError: "", | ||
}, | ||
{ | ||
name: "SetWorkflowIDError", | ||
prepareEnv: func() *cli.Context { | ||
// Create CLI app and set up flag set without FlagWorkflowID | ||
app := cli.NewApp() | ||
set := flag.NewFlagSet("test", 0) | ||
set.String(FlagDomain, "", "domain flag") // Only Domain flag is set | ||
c := cli.NewContext(app, set, nil) | ||
|
||
// Set only the domain flag, so setting FlagWorkflowID should trigger an error | ||
_ = c.Set(FlagDomain, common.SystemLocalDomainName) | ||
|
||
return c | ||
}, | ||
expectedError: "no such flag -workflow_id", | ||
}, | ||
{ | ||
name: "SetDomainError", | ||
prepareEnv: func() *cli.Context { | ||
// Create CLI app and set up flag set without FlagDomain | ||
app := cli.NewApp() | ||
set := flag.NewFlagSet("test", 0) | ||
set.String(FlagWorkflowID, "", "workflow ID flag") // Only Workflow ID flag is set | ||
c := cli.NewContext(app, set, nil) | ||
|
||
// Set workflow ID flag, but not the domain flag | ||
_ = c.Set(FlagWorkflowID, failovermanager.RebalanceWorkflowID) | ||
|
||
return c | ||
}, | ||
expectedError: "no such flag -domain", | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
// Prepare the test environment for the specific test case | ||
c := tt.prepareEnv() | ||
|
||
// Call AdminRebalanceList | ||
err := AdminRebalanceList(c) | ||
|
||
// Check the result based on the expected outcome | ||
if tt.expectedError != "" { | ||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), tt.expectedError) | ||
} else { | ||
assert.NoError(t, err) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestAdminAddSearchAttribute_errors(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
setupContext func(app *cli.App) *cli.Context | ||
expectedError string | ||
}{ | ||
{ | ||
name: "MissingSearchAttributesKey", | ||
setupContext: func(app *cli.App) *cli.Context { | ||
// Simulate missing FlagSearchAttributesKey | ||
set := flag.NewFlagSet("test", 0) | ||
// No FlagSearchAttributesKey set | ||
return cli.NewContext(app, set, nil) | ||
}, | ||
expectedError: "Required flag not present:", | ||
}, | ||
{ | ||
name: "InvalidSearchAttributeKey", | ||
setupContext: func(app *cli.App) *cli.Context { | ||
// Provide an invalid key to trigger ValidateSearchAttributeKey error | ||
set := flag.NewFlagSet("test", 0) | ||
set.String(FlagSearchAttributesKey, "123_invalid_key", "Key flag") // Invalid key, starts with number | ||
return cli.NewContext(app, set, nil) | ||
}, | ||
expectedError: "Invalid search-attribute key.", | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
// Create CLI app | ||
app := cli.NewApp() | ||
|
||
// Set up the CLI context for the specific test case | ||
c := tt.setupContext(app) | ||
|
||
// Call AdminAddSearchAttribute | ||
err := AdminAddSearchAttribute(c) | ||
|
||
// Check the result based on the expected outcome | ||
if tt.expectedError != "" { | ||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), tt.expectedError) | ||
} else { | ||
assert.NoError(t, err) | ||
} | ||
}) | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not needed