-
Notifications
You must be signed in to change notification settings - Fork 73
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #520 from newrelic/chore/report-status
chore(install): add nerdstorageExecutionStatusReporter
- Loading branch information
Showing
20 changed files
with
825 additions
and
81 deletions.
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
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 |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package install | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/google/uuid" | ||
) | ||
|
||
type executionStatusRollup struct { | ||
Complete bool `json:"complete"` | ||
DocumentID string | ||
EntityGuids []string `json:"entityGuids"` | ||
Statuses []executionStatus `json:"recipes"` | ||
Timestamp int64 `json:"timestamp"` | ||
} | ||
|
||
type executionStatus struct { | ||
Name string `json:"name"` | ||
DisplayName string `json:"displayName"` | ||
Status executionStatusType `json:"status"` | ||
Errors []executionStatusRecipeError `json:"errors"` | ||
} | ||
|
||
type executionStatusType string | ||
|
||
var executionStatusTypes = struct { | ||
AVAILABLE executionStatusType | ||
FAILED executionStatusType | ||
INSTALLED executionStatusType | ||
SKIPPED executionStatusType | ||
}{ | ||
AVAILABLE: "AVAILABLE", | ||
FAILED: "FAILED", | ||
INSTALLED: "INSTALLED", | ||
SKIPPED: "SKIPPED", | ||
} | ||
|
||
type executionStatusRecipeError struct { | ||
Message string `json:"message"` | ||
Details string `json:"details"` | ||
} | ||
|
||
func newExecutionStatusRollup() executionStatusRollup { | ||
s := executionStatusRollup{ | ||
DocumentID: uuid.New().String(), | ||
Timestamp: getTimestamp(), | ||
} | ||
|
||
return s | ||
} | ||
|
||
func getTimestamp() int64 { | ||
return time.Now().Unix() | ||
} | ||
|
||
func (s *executionStatusRollup) withAvailableRecipes(recipes []recipe) { | ||
for _, r := range recipes { | ||
e := recipeStatusEvent{recipe: r} | ||
s.withRecipeEvent(e, executionStatusTypes.AVAILABLE) | ||
} | ||
} | ||
|
||
func (s *executionStatusRollup) withRecipeEvent(e recipeStatusEvent, rs executionStatusType) { | ||
found := s.getExecutionStatusRecipe(e.recipe) | ||
|
||
if found != nil { | ||
found.Status = rs | ||
} else { | ||
e := &executionStatus{ | ||
Name: e.recipe.Name, | ||
DisplayName: e.recipe.DisplayName, | ||
Status: rs, | ||
} | ||
s.Statuses = append(s.Statuses, *e) | ||
} | ||
|
||
s.Timestamp = getTimestamp() | ||
} | ||
|
||
func (s *executionStatusRollup) getExecutionStatusRecipe(r recipe) *executionStatus { | ||
var found *executionStatus | ||
for i, recipe := range s.Statuses { | ||
if recipe.Name == r.Name { | ||
found = &s.Statuses[i] | ||
} | ||
} | ||
|
||
return found | ||
} |
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 |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package install | ||
|
||
type executionStatusReporter interface { | ||
reportRecipeFailed(event recipeStatusEvent) error | ||
reportRecipeInstalled(event recipeStatusEvent) error | ||
reportRecipesAvailable(recipes []recipe) error | ||
} | ||
|
||
type recipeStatusEvent struct { | ||
recipe recipe | ||
msg string | ||
entityGUID string | ||
} |
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 |
---|---|---|
@@ -0,0 +1,67 @@ | ||
//+ build unit | ||
package install | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestNewExecutionStatus(t *testing.T) { | ||
s := newExecutionStatusRollup() | ||
require.NotEmpty(t, s.Timestamp) | ||
require.NotEmpty(t, s.DocumentID) | ||
} | ||
|
||
func TestExecutionStatusWithAvailableRecipes_Basic(t *testing.T) { | ||
s := newExecutionStatusRollup() | ||
r := []recipe{{ | ||
Name: "testRecipe1", | ||
}, { | ||
Name: "testRecipe2", | ||
}} | ||
|
||
s.withAvailableRecipes(r) | ||
|
||
require.NotEmpty(t, s.Statuses) | ||
require.Equal(t, len(r), len(s.Statuses)) | ||
for _, recipeStatus := range s.Statuses { | ||
require.Equal(t, executionStatusTypes.AVAILABLE, recipeStatus.Status) | ||
} | ||
} | ||
|
||
func TestExecutionStatusWithRecipeEvent_Basic(t *testing.T) { | ||
s := newExecutionStatusRollup() | ||
r := recipe{Name: "testRecipe"} | ||
e := recipeStatusEvent{recipe: r} | ||
|
||
s.Timestamp = 0 | ||
s.withRecipeEvent(e, executionStatusTypes.INSTALLED) | ||
|
||
require.NotEmpty(t, s.Statuses) | ||
require.Equal(t, 1, len(s.Statuses)) | ||
require.Equal(t, executionStatusTypes.INSTALLED, s.Statuses[0].Status) | ||
require.NotEmpty(t, s.Timestamp) | ||
} | ||
|
||
func TestExecutionStatusWithRecipeEvent_RecipeExists(t *testing.T) { | ||
s := newExecutionStatusRollup() | ||
r := recipe{Name: "testRecipe"} | ||
e := recipeStatusEvent{recipe: r} | ||
|
||
s.Timestamp = 0 | ||
s.withRecipeEvent(e, executionStatusTypes.AVAILABLE) | ||
|
||
require.NotEmpty(t, s.Statuses) | ||
require.Equal(t, 1, len(s.Statuses)) | ||
require.Equal(t, executionStatusTypes.AVAILABLE, s.Statuses[0].Status) | ||
require.NotEmpty(t, s.Timestamp) | ||
|
||
s.Timestamp = 0 | ||
s.withRecipeEvent(e, executionStatusTypes.INSTALLED) | ||
|
||
require.NotEmpty(t, s.Statuses) | ||
require.Equal(t, 1, len(s.Statuses)) | ||
require.Equal(t, executionStatusTypes.INSTALLED, s.Statuses[0].Status) | ||
require.NotEmpty(t, s.Timestamp) | ||
} |
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 |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package install | ||
|
||
type mockExecutionStatusReporter struct { | ||
reportRecipesAvailableErr error | ||
reportRecipeFailedErr error | ||
reportRecipeInstalledErr error | ||
reportRecipesAvailableCallCount int | ||
reportRecipeFailedCallCount int | ||
reportRecipeInstalledCallCount int | ||
} | ||
|
||
func newMockExecutionStatusReporter() *mockExecutionStatusReporter { | ||
return &mockExecutionStatusReporter{} | ||
} | ||
|
||
func (r *mockExecutionStatusReporter) reportRecipeFailed(event recipeStatusEvent) error { | ||
r.reportRecipeFailedCallCount++ | ||
return r.reportRecipeFailedErr | ||
} | ||
|
||
func (r *mockExecutionStatusReporter) reportRecipeInstalled(event recipeStatusEvent) error { | ||
r.reportRecipeInstalledCallCount++ | ||
return r.reportRecipeInstalledErr | ||
} | ||
|
||
func (r *mockExecutionStatusReporter) reportRecipesAvailable(recipes []recipe) error { | ||
r.reportRecipesAvailableCallCount++ | ||
return r.reportRecipesAvailableErr | ||
} |
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 |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package install | ||
|
||
import "github.com/newrelic/newrelic-client-go/pkg/nerdstorage" | ||
|
||
// nolint:unused,deadcode | ||
type mockNerdstorageClient struct { | ||
respBody interface{} | ||
userScopeError error | ||
entityScopeError error | ||
writeDocumentWithUserScopeCallCount int | ||
writeDocumentWithEntityScopeCallCount int | ||
} | ||
|
||
// nolint:unused,deadcode | ||
func newMockNerdstorageClient() *mockNerdstorageClient { | ||
return &mockNerdstorageClient{ | ||
respBody: struct{}{}, | ||
userScopeError: nil, | ||
entityScopeError: nil, | ||
} | ||
} | ||
|
||
func (c *mockNerdstorageClient) WriteDocumentWithUserScope(nerdstorage.WriteDocumentInput) (interface{}, error) { | ||
c.writeDocumentWithUserScopeCallCount++ | ||
return c.respBody, c.userScopeError | ||
} | ||
|
||
func (c *mockNerdstorageClient) WriteDocumentWithEntityScope(string, nerdstorage.WriteDocumentInput) (interface{}, error) { | ||
c.writeDocumentWithEntityScopeCallCount++ | ||
return c.respBody, c.entityScopeError | ||
} |
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 |
---|---|---|
@@ -1,42 +1,58 @@ | ||
package install | ||
|
||
import "context" | ||
import ( | ||
"context" | ||
) | ||
|
||
type mockRecipeFetcher struct { | ||
fetchRecipeFunc func(*discoveryManifest, string) (*recipe, error) | ||
fetchRecipesFunc func() ([]recipe, error) | ||
fetchRecommendationsFunc func(*discoveryManifest) ([]recipe, error) | ||
fetchRecipeErr error | ||
fetchRecipesErr error | ||
fetchRecommendationsErr error | ||
fetchRecipeCallCount int | ||
fetchRecipesCallCount int | ||
fetchRecommendationsCallCount int | ||
fetchRecipeVals []recipe | ||
fetchRecipeVal *recipe | ||
fetchRecipesVal []recipe | ||
fetchRecommendationsVal []recipe | ||
} | ||
|
||
func newMockRecipeFetcher() *mockRecipeFetcher { | ||
f := mockRecipeFetcher{} | ||
f.fetchRecipeFunc = defaultFetchRecipeFunc | ||
f.fetchRecipesFunc = defaultFetchRecipesFunc | ||
f.fetchRecommendationsFunc = defaultFetchRecommendationsFunc | ||
|
||
f.fetchRecipesVal = []recipe{} | ||
f.fetchRecommendationsVal = []recipe{} | ||
return &f | ||
} | ||
|
||
func (f *mockRecipeFetcher) fetchRecipe(ctx context.Context, manifest *discoveryManifest, friendlyName string) (*recipe, error) { | ||
return f.fetchRecipeFunc(manifest, friendlyName) | ||
f.fetchRecipeCallCount++ | ||
|
||
if len(f.fetchRecipeVals) > 0 { | ||
i := minOf(f.fetchRecipeCallCount, len(f.fetchRecipeVals)) - 1 | ||
return &f.fetchRecipeVals[i], f.fetchRecipesErr | ||
} | ||
|
||
return f.fetchRecipeVal, f.fetchRecipeErr | ||
} | ||
|
||
func (f *mockRecipeFetcher) fetchRecipes(ctx context.Context) ([]recipe, error) { | ||
return f.fetchRecipesFunc() | ||
f.fetchRecipesCallCount++ | ||
return f.fetchRecipesVal, f.fetchRecipesErr | ||
} | ||
|
||
func (f *mockRecipeFetcher) fetchRecommendations(ctx context.Context, manifest *discoveryManifest) ([]recipe, error) { | ||
return f.fetchRecommendationsFunc(manifest) | ||
f.fetchRecommendationsCallCount++ | ||
return f.fetchRecommendationsVal, f.fetchRecommendationsErr | ||
} | ||
|
||
func defaultFetchRecipeFunc(manifest *discoveryManifest, friendlyName string) (*recipe, error) { | ||
return &recipe{}, nil | ||
} | ||
func minOf(vars ...int) int { | ||
min := vars[0] | ||
|
||
func defaultFetchRecommendationsFunc(manifest *discoveryManifest) ([]recipe, error) { | ||
return []recipe{}, nil | ||
} | ||
for _, i := range vars { | ||
if min > i { | ||
min = i | ||
} | ||
} | ||
|
||
func defaultFetchRecipesFunc() ([]recipe, error) { | ||
return []recipe{}, nil | ||
return min | ||
} |
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
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 |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package install | ||
|
||
import ( | ||
"github.com/newrelic/newrelic-client-go/pkg/nerdstorage" | ||
) | ||
|
||
type nerdstorageClient interface { | ||
WriteDocumentWithUserScope(nerdstorage.WriteDocumentInput) (interface{}, error) | ||
WriteDocumentWithEntityScope(string, nerdstorage.WriteDocumentInput) (interface{}, error) | ||
} |
Oops, something went wrong.