UNPKG

@cloud-carbon-footprint/aws

Version:

The core logic to get cloud usage data and estimate energy and carbon emissions from Amazon Web Services.

182 lines (164 loc) 5.1 kB
/* * © 2021 Thoughtworks, Inc. */ import { mockClient } from 'aws-sdk-client-mock' import S3 from '../lib/S3' import { ServiceWrapper } from '../lib' import mockAWSCloudWatchGetMetricDataCall from '../lib/mockAWSCloudWatchGetMetricDataCall' import { buildCostExplorerGetCostResponse } from './fixtures/builders' import { CloudWatchClient } from '@aws-sdk/client-cloudwatch' import { CostExplorerClient, GetCostAndUsageCommand, } from '@aws-sdk/client-cost-explorer' import { CloudWatchLogsClient } from '@aws-sdk/client-cloudwatch-logs' import { S3Client } from '@aws-sdk/client-s3' const cloudWatchMock = mockClient(CloudWatchClient) const costExplorerMock = mockClient(CostExplorerClient) describe('S3', () => { afterEach(() => { costExplorerMock.reset() cloudWatchMock.reset() }) const region = 'us-east-1' const start = '2020-08-01T00:00:00.000Z' const dayTwo = '2020-08-02T00:00:00.000Z' const dayThree = '2020-08-03T00:00:00.000Z' const end = '2020-08-04T00:00:00.000Z' const metricDataQueries = [ { Id: 's3Size', Expression: 'SUM(SEARCH(\'{AWS/S3,BucketName,StorageType} MetricName="BucketSizeBytes" StorageType="StandardStorage"\', \'Average\', 86400))', }, ] const getServiceWrapper = () => new ServiceWrapper( new CloudWatchClient(), new CloudWatchLogsClient(), new CostExplorerClient(), new S3Client(), ) it('gets S3 usage', async () => { const response: any = { MetricDataResults: [ { Id: 's3Size', Label: 's3Size', Timestamps: [start, dayTwo, dayThree, end], Values: [2586032500, 3286032500, 7286032500, 4286032500], StatusCode: 'Complete', Messages: [], }, ], } mockAWSCloudWatchGetMetricDataCall( new Date(start), new Date(end), response, metricDataQueries, ) const s3Service = new S3(getServiceWrapper()) const result = await s3Service.getUsage(new Date(start), new Date(end)) expect(result).toEqual([ { terabyteHours: 0.0564475885767024, timestamp: new Date(start), }, { terabyteHours: 0.0717270995664876, timestamp: new Date(dayTwo), }, { terabyteHours: 0.1590385909366887, timestamp: new Date(dayThree), }, { terabyteHours: 0.09355497240903787, timestamp: new Date(end), }, ]) }) it('gets S3 cost for two days', async () => { costExplorerMock.on(GetCostAndUsageCommand).resolves( buildCostExplorerGetCostResponse([ { start, amount: 2.3, keys: ['Amazon Simple Storage Service'] }, { start: dayTwo, amount: 4.6, keys: ['test'] }, ]), ) const s3Service = new S3(getServiceWrapper()) const s3Costs = await s3Service.getCosts( new Date(start), new Date(end), region, ) expect(s3Costs).toEqual([ { amount: 2.3, currency: 'USD', timestamp: new Date(start) }, { amount: 4.6, currency: 'USD', timestamp: new Date(dayTwo) }, ]) }) it('throw Partial Data Error if partial data returned', async () => { const response: any = { MetricDataResults: [ { Id: 's3Size', Label: 's3Size', Timestamps: [start, dayTwo, dayThree, end], Values: [2586032500, 3286032500, 7286032500, 4286032500], StatusCode: 'Complete', Messages: [], }, { Id: 's3Size', Label: 's3Size', Timestamps: [start, dayTwo, dayThree, end], Values: [2586032500, 3286032500, 7286032500, 4286032500], StatusCode: 'PartialData', Messages: [], }, ], } mockAWSCloudWatchGetMetricDataCall( new Date(start), new Date(end), response, metricDataQueries, ) const s3Service = new S3(getServiceWrapper()) const getS3Usage = async () => await s3Service.getUsage(new Date(start), new Date(end)) await expect(getS3Usage).rejects.toThrow('Partial Data Returned from AWS') }) it('do not throw Partial Data Error if complete data is returned', async () => { const response: any = { MetricDataResults: [ { Id: 's3Size', Label: 's3Size', Timestamps: [start, dayTwo, dayThree, end], Values: [2586032500, 3286032500, 7286032500, 4286032500], StatusCode: 'Complete', Messages: [], }, { Id: 's3Size', Label: 's3Size', Timestamps: [start, dayTwo, dayThree, end], Values: [2586032500, 3286032500, 7286032500, 4286032500], StatusCode: 'Complete', Messages: [], }, ], } mockAWSCloudWatchGetMetricDataCall( new Date(start), new Date(end), response, metricDataQueries, ) const s3Service = new S3(getServiceWrapper()) const getS3Usage = async () => await s3Service.getUsage(new Date(start), new Date(end)) await expect(getS3Usage).not.toThrow() }) })