From dc1a24e4d4da158ab0043f546bf76d055ca3c320 Mon Sep 17 00:00:00 2001 From: Rendani Gangazhe Date: Sat, 27 May 2023 14:05:42 +0200 Subject: [PATCH] Adjust JobMetrics component tests and add AwsEstimate component tests --- .../components/JobMetrics/AwsEstimate.test.js | 86 +++++++++++++++++++ .../src/components/JobMetrics/AwsEstimate.vue | 63 +++++++------- .../components/JobMetrics/JobMetrics.test.js | 73 ---------------- .../src/components/JobMetrics/JobMetrics.vue | 12 +-- 4 files changed, 122 insertions(+), 112 deletions(-) create mode 100644 client/src/components/JobMetrics/AwsEstimate.test.js diff --git a/client/src/components/JobMetrics/AwsEstimate.test.js b/client/src/components/JobMetrics/AwsEstimate.test.js new file mode 100644 index 00000000000..22008d49877 --- /dev/null +++ b/client/src/components/JobMetrics/AwsEstimate.test.js @@ -0,0 +1,86 @@ +import ec2 from "./ec2.json"; +import flushPromises from "flush-promises"; +import { getLocalVue } from "tests/jest/helpers"; +import AwsEstimate from "./AwsEstimate"; +import { mount } from "@vue/test-utils"; + +// Ignore all axios calls, data is mocked locally -- just say "OKAY!" +jest.mock("axios", () => ({ + get: async () => { + return { response: { status: 200 } }; + }, +})); + +const localVue = getLocalVue(); + +describe("JobMetrics/AwsEstimate.vue", () => { + it("renders nothing if no matching EC2 instance exists.", async () => { + const wrapper = mount(AwsEstimate, { + propsData: { + jobId: "0", + jobRuntime: 0, + coresAllocated: -999, + memoryAllocated: -999, + }, + localVue, + }); + + await wrapper.vm.$nextTick(); + expect(wrapper.find("#aws-name").exists()).toBe(false); + }); + + it("renders correct AWS estimates.", async () => { + const deriveRenderedAwsEstimate = async (cores, seconds, memory) => { + const JOB_ID = Math.random().toString(36).substring(2); + + const wrapper = mount(AwsEstimate, { + localVue, + propsData: { + jobId: JOB_ID, + jobRuntime: Number(seconds), + coresAllocated: Number(cores), + memoryAllocated: Number(memory), + }, + }); + + // Wait for axios and rendering. + await flushPromises(); + + if (wrapper.find("#aws-estimate").exists()) { + return { + cost: wrapper.find("#aws-cost").text(), + vcpus: wrapper.find("#aws-vcpus").text(), + cpu: wrapper.find("#aws-cpu").text(), + mem: wrapper.find("#aws-mem").text(), + name: wrapper.find("#aws-name").text(), + }; + } + + return {}; + }; + + const assertAwsInstance = (estimates) => { + const instance = ec2.find((instance) => estimates.name === instance.name); + expect(estimates.mem).toBe(instance.mem.toString()); + expect(estimates.vcpus).toBe(instance.vcpus.toString()); + expect(estimates.cpu).toBe(instance.cpu.join(", ")); + }; + + const estimates_small = await deriveRenderedAwsEstimate("1.0000000", "9.0000000", "2048.0000000"); + expect(estimates_small.name).toBe("t2.small"); + expect(estimates_small.cost).toBe("0.00 USD"); + assertAwsInstance(estimates_small); + + const estimates_large = await deriveRenderedAwsEstimate("40.0000000", "18000.0000000", "194560.0000000"); + expect(estimates_large.name).toBe("m5d.12xlarge"); + expect(estimates_large.cost).toBe("16.32 USD"); + assertAwsInstance(estimates_large); + + const estimates_not_available = await deriveRenderedAwsEstimate( + "99999.0000000", + "18000.0000000", + "99999.0000000" + ); + expect(estimates_not_available).toEqual({}); + }); +}); diff --git a/client/src/components/JobMetrics/AwsEstimate.vue b/client/src/components/JobMetrics/AwsEstimate.vue index 9321af2bc7a..fab331cadae 100644 --- a/client/src/components/JobMetrics/AwsEstimate.vue +++ b/client/src/components/JobMetrics/AwsEstimate.vue @@ -5,60 +5,55 @@ import ec2 from "./ec2.json"; export interface AwsEstimateProps { jobRuntime: number; coresAllocated: number; - memoryAllocated: number; + memoryAllocated?: number; } -const props = withDefaults(defineProps(), { - memoryAllocated: 0.5, -}); +const props = defineProps(); const computedAwsEstimate = computed(() => { - const aws: Record = {}; - const { coresAllocated, jobRuntime, memoryAllocated } = props; - aws.seconds = jobRuntime; - aws.vcpus = coresAllocated; - aws.memory = memoryAllocated; - - if (aws.memory) { - aws.memory /= 1024; - } else { - // if memory was not specified, assign the smallest amount (we judge based on CPU-count only) - aws.memory = 0.5; - } - - // Estimate EC2 instance. Data is already sorted - aws.instance = ec2.find((ec) => { - return ec.mem >= aws.memory && ec.vcpus >= aws.vcpus; - }); - - if (!aws.instance) { + if (coresAllocated <= 0 || jobRuntime <= 0) { return; } - aws.price = ((aws.seconds * aws.instance.price) / 3600).toFixed(2); + const adjustedMemoryAllocated = memoryAllocated ? memoryAllocated / 1024 : 0.5; - return aws; + // Estimate EC2 instance. Data is already sorted + const ec2Instance = ec2.find((ec) => { + return ec.mem >= adjustedMemoryAllocated && ec.vcpus >= coresAllocated; + }); + + if (!ec2Instance) { + return; + } + + return { + seconds: jobRuntime, + vcpus: coresAllocated, + memory: adjustedMemoryAllocated, + price: ((jobRuntime * ec2Instance.price) / 3600).toFixed(2), + instance: ec2Instance + }; });