diff --git a/client/src/api/schema/schema.ts b/client/src/api/schema/schema.ts index a5ec94d89576..1f15d98049a4 100644 --- a/client/src/api/schema/schema.ts +++ b/client/src/api/schema/schema.ts @@ -866,6 +866,13 @@ export interface paths { /** Materialize a deferred library or HDA dataset into real, usable dataset in specified history. */ post: operations["materialize_to_history_api_histories__history_id__materialize_post"]; }; + "/api/histories/{history_id}/metrics": { + /** + * Get the cumulative metrics of all jobs in a given history. + * @description Get the cumulative metrics of all jobs in a history with ``history_id``. + */ + get: operations["get_metrics_api_histories__history_id__metrics_get"]; + }; "/api/histories/{history_id}/prepare_store_download": { /** Return a short term storage token to monitor download of the history. */ post: operations["prepare_store_download_api_histories__history_id__prepare_store_download_post"]; @@ -1000,6 +1007,13 @@ export interface paths { */ get: operations["invocation_jobs_summary_api_invocations__invocation_id__jobs_summary_get"]; }; + "/api/invocations/{invocation_id}/metrics": { + /** + * Get the cumulative metrics of all jobs in a given workflow invocation. + * @description Get the cumulative metrics of all jobs in a workflow invocation with ``invocation_id``. + */ + get: operations["get_metrics_api_invocations__invocation_id__metrics_get"]; + }; "/api/invocations/{invocation_id}/prepare_store_download": { /** Prepare a workflow invocation export-style download. */ post: operations["prepare_store_download_api_invocations__invocation_id__prepare_store_download_post"]; @@ -8957,6 +8971,21 @@ export interface components { */ time: string; }; + /** MetricsSummaryCumulative */ + MetricsSummaryCumulative: { + /** Total Allocated Cores Cpu */ + total_allocated_cores_cpu: number; + /** Total Allocated Memory Mebibyte */ + total_allocated_memory_mebibyte: number; + /** Total Energy Needed Cpu Kwh */ + total_energy_needed_cpu_kwh: number; + /** Total Energy Needed Kwh */ + total_energy_needed_kwh: number; + /** Total Energy Needed Memory Kwh */ + total_energy_needed_memory_kwh: number; + /** Total Runtime Seconds */ + total_runtime_seconds: number; + }; /** * ModelStoreFormat * @description Available types of model stores for export. @@ -17496,6 +17525,36 @@ export interface operations { }; }; }; + get_metrics_api_histories__history_id__metrics_get: { + /** + * Get the cumulative metrics of all jobs in a given history. + * @description Get the cumulative metrics of all jobs in a history with ``history_id``. + */ + parameters: { + /** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */ + header?: { + "run-as"?: string | null; + }; + /** @description The encoded database identifier of the History. */ + path: { + history_id: string; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + content: { + "application/json": components["schemas"]["MetricsSummaryCumulative"]; + }; + }; + /** @description Validation Error */ + 422: { + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; prepare_store_download_api_histories__history_id__prepare_store_download_post: { /** Return a short term storage token to monitor download of the history. */ parameters: { @@ -18171,6 +18230,36 @@ export interface operations { }; }; }; + get_metrics_api_invocations__invocation_id__metrics_get: { + /** + * Get the cumulative metrics of all jobs in a given workflow invocation. + * @description Get the cumulative metrics of all jobs in a workflow invocation with ``invocation_id``. + */ + parameters: { + /** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */ + header?: { + "run-as"?: string | null; + }; + /** @description The encoded database identifier of the Invocation. */ + path: { + invocation_id: string; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + content: { + "application/json": components["schemas"]["MetricsSummaryCumulative"]; + }; + }; + /** @description Validation Error */ + 422: { + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; prepare_store_download_api_invocations__invocation_id__prepare_store_download_post: { /** Prepare a workflow invocation export-style download. */ parameters: { diff --git a/client/src/components/JobMetrics/CarbonEmissions/BarChart.vue b/client/src/components/CarbonEmissions/BarChart.vue similarity index 100% rename from client/src/components/JobMetrics/CarbonEmissions/BarChart.vue rename to client/src/components/CarbonEmissions/BarChart.vue diff --git a/client/src/components/JobMetrics/CarbonEmissions/CarbonEmissionCard.vue b/client/src/components/CarbonEmissions/CarbonEmissionCard.vue similarity index 100% rename from client/src/components/JobMetrics/CarbonEmissions/CarbonEmissionCard.vue rename to client/src/components/CarbonEmissions/CarbonEmissionCard.vue diff --git a/client/src/components/CarbonEmissions/CarbonEmissions.test.ts b/client/src/components/CarbonEmissions/CarbonEmissions.test.ts new file mode 100644 index 000000000000..eeb1d34f51d6 --- /dev/null +++ b/client/src/components/CarbonEmissions/CarbonEmissions.test.ts @@ -0,0 +1,84 @@ +import { createTestingPinia } from "@pinia/testing"; +import { mount } from "@vue/test-utils"; +import { getLocalVue } from "tests/jest/helpers"; +import { ref } from "vue"; + +import { worldwideCarbonIntensity } from "./carbonEmissionConstants"; + +import CarbonEmissions from "./CarbonEmissions.vue"; + +const carbonIntensity = ref(worldwideCarbonIntensity); +const geographicalServerLocationName = ref("GLOBAL"); +jest.mock("@/composables/carbonEmissions", () => ({ + useCarbonEmissions: () => { + return { + carbonIntensity, + geographicalServerLocationName, + }; + }, +})); + +const localVue = getLocalVue(); +const pinia = createTestingPinia(); +const slots = { + header: "
foo
", + footer: "
bar
", +}; + +describe("CarbonEmissions/CarbonEmissions.vue", () => { + it("correctly calculates carbon emissions.", () => { + const wrapper = mount(CarbonEmissions as any, { + propsData: { + energyNeededCPU: 0.015, + energyNeededMemory: 0.005, + }, + pinia, + slots, + localVue, + }); + + const cpuEmissions = wrapper.find("#cpu-carbon-emissions").text(); + const memoryEmissions = wrapper.find("#memory-carbon-emissions").text(); + const cpuEnergyUsage = wrapper.find("#cpu-energy-usage").text(); + const memoryEnergyUsage = wrapper.find("#memory-energy-usage").text(); + + expect(cpuEmissions).toMatch("7 g CO2e"); + expect(memoryEmissions).toMatch("2 g CO2e"); + expect(cpuEnergyUsage).toMatch("15 mW⋅h"); + expect(memoryEnergyUsage).toMatch("5 mW⋅h"); + }); + + it("does not render any data for memory if its memroy usage is 0.", () => { + const wrapper = mount(CarbonEmissions as any, { + propsData: { + energyNeededCPU: 0, + energyNeededMemory: 0, + }, + pinia, + slots, + localVue, + }); + + expect(wrapper.find("#memory-energy-usage").exists()).toBe(false); + expect(wrapper.find("#memroy-carbon-emissions").exists()).toBe(false); + }); + + it("takes the configured `carbonIntensity` value into account.", () => { + carbonIntensity.value = 0; + const wrapper = mount(CarbonEmissions as any, { + propsData: { + energyNeededCPU: 1_000, + energyNeededMemory: 1_000, + }, + pinia, + slots, + localVue, + }); + + const cpuEmissions = wrapper.find("#cpu-carbon-emissions").text(); + const memoryEmissions = wrapper.find("#memory-carbon-emissions").text(); + + expect(cpuEmissions).toMatch("0 g CO2e"); + expect(memoryEmissions).toMatch("0 g CO2e"); + }); +}); diff --git a/client/src/components/JobMetrics/CarbonEmissions/CarbonEmissions.vue b/client/src/components/CarbonEmissions/CarbonEmissions.vue similarity index 67% rename from client/src/components/JobMetrics/CarbonEmissions/CarbonEmissions.vue rename to client/src/components/CarbonEmissions/CarbonEmissions.vue index f124643cecbc..51daa5d297ac 100644 --- a/client/src/components/JobMetrics/CarbonEmissions/CarbonEmissions.vue +++ b/client/src/components/CarbonEmissions/CarbonEmissions.vue @@ -1,81 +1,48 @@ -