UNPKG

@cloud-carbon-footprint/gcp

Version:

The core logic to get cloud usage data and estimate energy and carbon emissions from Google Cloud Platform.

206 lines (179 loc) 5.54 kB
/* * © 2021 Thoughtworks, Inc. */ import { GoogleAuth } from 'google-auth-library' import { ComputeEngine, Recommendations } from '../lib' import { setConfig, EstimationResult, GroupBy, RecommendationResult, } from '@cloud-carbon-footprint/common' import { Region, RegionCosts, RegionEstimates, } from '@cloud-carbon-footprint/core' const mockMetricServiceClient = jest.fn() jest.mock('@google-cloud/monitoring', () => { return { v3: { MetricServiceClient: mockMetricServiceClient, }, } }) describe('GCPAccount', () => { const projectId = 'test-project' /* eslint-disable @typescript-eslint/no-var-requires */ afterEach(() => { jest.restoreAllMocks() }) it('should return empty if no service in config file', () => { setConfig({ GCP: { CURRENT_SERVICES: [], }, }) const GCPAccount = require('../application/GCPAccount').default const services = new GCPAccount(['us-east1']).getServices() expect(services).toHaveLength(0) }) it('should throw error if unknown service', () => { setConfig({ GCP: { CURRENT_SERVICES: [{ key: 'goose', name: '' }], }, }) const GCPAccount = require('../application/GCPAccount').default const account = new GCPAccount(['us-east1']) expect(() => { account.getServices() }).toThrowError('Unsupported service: goose') }) it('should return computeEngine instance and inject MetricServiceClient', () => { expectGCPService('computeEngine').toBeInstanceOf(ComputeEngine) expect(mockMetricServiceClient).toHaveBeenCalledWith({ projectId: projectId, }) }) it('should get data for regions', async () => { // given const startDate: Date = new Date('2020-01-01') const endDate: Date = new Date('2020-01-02') const grouping: GroupBy = GroupBy.day const expectedEstimatesData: RegionEstimates = { ComputeEngine: [ { timestamp: startDate, kilowattHours: 10, co2e: 2, usesAverageCPUConstant: false, }, ], } const getEstimatesSpy = jest.spyOn(Region.prototype, 'getEstimates') getEstimatesSpy.mockResolvedValue(expectedEstimatesData) const expectedCostData: RegionCosts = { ComputeEngine: [ { timestamp: startDate, amount: 1000, currency: 'USD', }, ], } const getCostsSpy = jest.spyOn(Region.prototype, 'getCosts') getCostsSpy.mockResolvedValue(expectedCostData) const regions: string[] = ['test-region-1', 'test-region-2'] const GCPAccount = require('../application/GCPAccount').default const testGCPAccount = new GCPAccount('12345678', 'test account', regions) // when const result = await testGCPAccount.getDataForRegions( startDate, endDate, grouping, ) // then const expectedResult: EstimationResult[] = [ { timestamp: startDate, serviceEstimates: [ { cloudProvider: 'GCP', kilowattHours: 10, co2e: 2, cost: 1000, usesAverageCPUConstant: false, accountId: '12345678', accountName: 'test account', serviceName: 'ComputeEngine', region: 'test-region-1', }, ], groupBy: grouping, periodEndDate: new Date('2020-01-01T23:59:59.000Z'), periodStartDate: new Date('2020-01-01T00:00:00.000Z'), }, { timestamp: startDate, serviceEstimates: [ { cloudProvider: 'GCP', kilowattHours: 10, co2e: 2, cost: 1000, usesAverageCPUConstant: false, accountId: '12345678', accountName: 'test account', serviceName: 'ComputeEngine', region: 'test-region-2', }, ], groupBy: grouping, periodEndDate: new Date('2020-01-01T23:59:59.000Z'), periodStartDate: new Date('2020-01-01T00:00:00.000Z'), }, ] expect(result).toEqual(expectedResult) }) it('should get data for gcp recommendations', async () => { const GCPAccount = require('../application/GCPAccount').default const testGCPAccount = new GCPAccount('12345678', 'test account', [ 'some-region', ]) const expectedRecommendations: RecommendationResult[] = [ { cloudProvider: 'GCP', accountId: 'account-id', accountName: 'account-name', region: 'us-east1', recommendationType: 'STOP_VM', recommendationDetail: "Save cost by stopping Idle VM 'test-instance'.", kilowattHourSavings: 5, co2eSavings: 4, costSavings: 3, }, ] const getClientSpy = jest.spyOn(GoogleAuth.prototype, 'getClient') ;(getClientSpy as jest.Mock).mockResolvedValue(jest.fn()) const getRecommendations = jest.spyOn( Recommendations.prototype, 'getRecommendations', ) getRecommendations.mockResolvedValue(expectedRecommendations) const result = await testGCPAccount.getDataForRecommendations() expect(result).toEqual(expectedRecommendations) }) }) function expectGCPService(key: string) { setConfig({ GCP: { CURRENT_SERVICES: [{ key: key, name: '' }], }, }) const GCPAccount = require('../application/GCPAccount').default const services = new GCPAccount('test-project', 'test project', [ 'us-east1', ]).getServices() return expect(services[0]) }