Skip to content

Commit

Permalink
Clean up code; add more tests (#44)
Browse files Browse the repository at this point in the history
Signed-off-by: Sajit Kunnumkal <[email protected]>
Co-authored-by: sajit <[email protected]>
  • Loading branch information
sajit and sajit authored Oct 17, 2024
1 parent 39e7d17 commit 5ebd41d
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 25 deletions.
34 changes: 16 additions & 18 deletions pkg/plugins/mongodb-atlas/cmd/main/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ var handshakeConfig = plugin.HandshakeConfig{
MagicCookieValue: "mongodb-atlas",
}

const costExplorerPendingInvoices = "https://cloud.mongodb.com/api/atlas/v2/orgs/%s/invoices/pending"
const costExplorerPendingInvoicesURL = "https://cloud.mongodb.com/api/atlas/v2/orgs/%s/invoices/pending"

func main() {
log.Debug("Initializing Mongo plugin")
Expand Down Expand Up @@ -155,15 +155,10 @@ func (a *AtlasCostSource) GetCustomCosts(req *pb.CustomCostRequest) []*pb.Custom
}

log.Debugf("fetching atlas costs for window %v", target)
result, err := a.getAtlasCostsForWindow(&target, lineItems)
if err != nil {
log.Errorf("error getting costs for window %v: %v", target, err)
errResp := pb.CustomCostResponse{}
errResp.Errors = append(errResp.Errors, fmt.Sprintf("error getting costs for window %v: %v", target, err))
results = append(results, &errResp)
} else {
results = append(results, result)
}
result := a.getAtlasCostsForWindow(&target, lineItems)

results = append(results, result)

}

return results
Expand All @@ -183,12 +178,15 @@ func filterLineItemsByWindow(win *opencost.Window, lineItems []atlasplugin.LineI

if err1 != nil || err2 != nil {
// If parsing fails, skip this item
if err1 != nil {
log.Warnf("%s", err1)
}
if err2 != nil {
log.Warnf("%s", err2)
}
continue
}
// // Iterate over the UsageDetails in CostResponse
// for _, lineItem := range pendingInvoicesResponse.LineItems {
// Create a new pb.CustomCost for each LineItem
//log.Debugf("Line item %v", item)

customCost := &pb.CustomCost{

AccountName: item.GroupName,
Expand Down Expand Up @@ -217,9 +215,9 @@ func filterLineItemsByWindow(win *opencost.Window, lineItems []atlasplugin.LineI

}

func (a *AtlasCostSource) getAtlasCostsForWindow(win *opencost.Window, lineItems []atlasplugin.LineItem) (*pb.CustomCostResponse, error) {
func (a *AtlasCostSource) getAtlasCostsForWindow(win *opencost.Window, lineItems []atlasplugin.LineItem) *pb.CustomCostResponse {

//filter responses between
//filter responses between the win start and win end dates

costsInWindow := filterLineItemsByWindow(win, lineItems)

Expand All @@ -234,11 +232,11 @@ func (a *AtlasCostSource) getAtlasCostsForWindow(win *opencost.Window, lineItems
Errors: []string{},
Costs: costsInWindow,
}
return &resp, nil
return &resp
}

func GetPendingInvoices(org string, client HTTPClient) ([]atlasplugin.LineItem, error) {
request, _ := http.NewRequest("GET", fmt.Sprintf(costExplorerPendingInvoices, org), nil)
request, _ := http.NewRequest("GET", fmt.Sprintf(costExplorerPendingInvoicesURL, org), nil)

request.Header.Set("Accept", "application/vnd.atlas.2023-01-01+json")
request.Header.Set("Content-Type", "application/vnd.atlas.2023-01-01+json")
Expand Down
89 changes: 82 additions & 7 deletions pkg/plugins/mongodb-atlas/cmd/main/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func TestGetCostsPendingInvoices(t *testing.T) {
if req.Method != http.MethodGet {
t.Errorf("expected GET request, got %s", req.Method)
}
expectedURL := fmt.Sprintf(costExplorerPendingInvoices, "myOrg")
expectedURL := fmt.Sprintf(costExplorerPendingInvoicesURL, "myOrg")
if req.URL.String() != expectedURL {
t.Errorf("expected URL %s, got %s", expectedURL, req.URL.String())
}
Expand Down Expand Up @@ -154,10 +154,7 @@ func TestGetCostErrorFromServer(t *testing.T) {
DoFunc: func(req *http.Request) (*http.Response, error) {

// Return a mock response with status 200 and mock JSON body
return &http.Response{
StatusCode: http.StatusInternalServerError,
Body: io.NopCloser(bytes.NewBufferString("")),
}, nil
return nil, fmt.Errorf("mock error: failed to execute request")
},
}
costs, err := GetPendingInvoices("myOrg", mockClient)
Expand Down Expand Up @@ -226,8 +223,7 @@ func TestGetAtlasCostsForWindow(t *testing.T) {

// Create a new Window instance
window := opencost.NewWindow(&day2, &day3)
resp, error := atlasCostSource.getAtlasCostsForWindow(&window, lineItems)
assert.Nil(t, error)
resp := atlasCostSource.getAtlasCostsForWindow(&window, lineItems)
assert.True(t, resp != nil)
assert.Equal(t, "data_storage", resp.CostSource)
assert.Equal(t, "mongodb-atlas", resp.Domain)
Expand Down Expand Up @@ -414,3 +410,82 @@ func TestFilterInvoicesOnWindow(t *testing.T) {
assert.Equal(t, lineItems[0].Quantity, filteredItems[0].UsageQuantity)
assert.Equal(t, filteredItems[0].UsageUnit, lineItems[0].Unit)
}

func TestFilterInvoicesOnWindowBadResponse(t *testing.T) {
//setup a window between october 1st and october 31st 2024
windowStart := time.Date(2024, time.October, 1, 0, 0, 0, 0, time.UTC)
windowEnd := time.Date(2024, time.October, 31, 0, 0, 0, 0, time.UTC)
window := opencost.NewWindow(&windowStart, &windowEnd)

//lineItems has bad startdate and bad endDate
lineItems := []atlasplugin.LineItem{
{StartDate: "Bar", EndDate: "Foo", UnitPriceDollars: 1.0, GroupName: "kubecost0",
SKU: "0", ClusterName: "cluster-0", GroupId: "A", TotalPriceCents: 45, Quantity: 2, Unit: "GB"}, // Within window
// Partially in window
}

filteredItems := filterLineItemsByWindow(&window, lineItems)
assert.Equal(t, 0, len(filteredItems))
}

func TestBadWindow(t *testing.T) {
pendingInvoiceResponse := atlasplugin.PendingInvoice{}

mockResponseJson, _ := json.Marshal(pendingInvoiceResponse)
mockClient := &MockHTTPClient{
DoFunc: func(req *http.Request) (*http.Response, error) {

//return costs
return &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(bytes.NewBuffer(mockResponseJson)),
}, nil

},
}
atlasCostSource := AtlasCostSource{
orgID: "myOrg",
atlasClient: mockClient,
}
now := time.Now()
currentMonthStart := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, time.UTC)
customCostRequest := pb.CustomCostRequest{
Start: timestamppb.New(currentMonthStart), // Start in current month
End: timestamppb.New(currentMonthStart.Add(5 * time.Hour)), // End in 5 hours
Resolution: durationpb.New(24 * time.Hour), // 1 day resolution

}
//this window should throw an error in the opencost.GetWindows method
resp := atlasCostSource.GetCustomCosts(&customCostRequest)
assert.True(t, len(resp[0].Errors) > 0)
}

func TestGetCostsReturnsErrorForPendingInvoices(t *testing.T) {

mockClient := &MockHTTPClient{
DoFunc: func(req *http.Request) (*http.Response, error) {

//return costs
return nil, fmt.Errorf("mock error: failed to execute request")

},
}
atlasCostSource := AtlasCostSource{
orgID: "myOrg",
atlasClient: mockClient,
}
// Define the start and end time for the window
now := time.Now()
currentMonthStart := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, time.UTC)

customCostRequest := pb.CustomCostRequest{
Start: timestamppb.New(currentMonthStart), // Start in current month
End: timestamppb.New(currentMonthStart.Add(48 * time.Hour)), // End in current month
Resolution: durationpb.New(24 * time.Hour), // 1 day resolution

}

resp := atlasCostSource.GetCustomCosts(&customCostRequest)
assert.True(t, len(resp[0].Errors) > 0)

}

0 comments on commit 5ebd41d

Please sign in to comment.