Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port and Vuefy AWS estimate from EU #9621

Merged
merged 2 commits into from
Apr 21, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
implent tests
  • Loading branch information
OlegZharkov committed Apr 17, 2020
commit c5084f4f37d61b24feab0d777be50508a3fd8cf0
60 changes: 60 additions & 0 deletions client/galaxy/scripts/components/JobMetrics/JobMetrics.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { mount, createLocalVue } from "@vue/test-utils";
import { createStore } from "../../store";
import flushPromises from "flush-promises";
import JobMetrics from "./JobMetrics";
import ec2 from "./ec2.json";

const JOB_ID = "moo";

Expand Down Expand Up @@ -65,4 +66,63 @@ describe("JobMetrics/JobMetrics.vue", () => {
expect(metricsTables.at(1).find(".metrics_plugin_title").text()).to.equals("extended");
expect(metricsTables.at(1).findAll("tr").length).to.equals(1);
});

it("should render correct AWS Estimates", async () => {
let deriveRenderedAwsEstimate = async (cores, seconds, memory) => {
const JOB_ID = Math.random().toString(36).substring(2);
const propsData = {
jobId: JOB_ID,
aws_estimate: "True",
};
const metricsResponse = [
{ plugin: "core", name: "galaxy_slots", raw_value: cores },
{ plugin: "core", name: "runtime_seconds", raw_value: seconds },
{ plugin: "core", name: "galaxy_memory_mb", raw_value: memory },
];
axiosMock.onGet(`/api/jobs/${JOB_ID}/metrics`).reply(200, metricsResponse);
const wrapper = mount(JobMetrics, {
store: testStore,
propsData,
localVue,
});
// Wait for axios and rendering.
await flushPromises();

const estimates = {};

if (!wrapper.find("#aws-estimate").exists()) return false;

estimates.cost = wrapper.find("#aws-estimate > b").text();
estimates.vcpus = wrapper.find("#aws_vcpus").text();
estimates.cpu = wrapper.find("#aws_cpu").text();
estimates.mem = wrapper.find("#aws_mem").text();
estimates.name = wrapper.find("#aws_name").text();

return estimates;
};
let assertAwsInstance = (estimates) => {
const instance = ec2.find((instance) => estimates.name === instance.name);
expect(estimates.mem).to.equals(instance.mem.toString());
expect(estimates.vcpus).to.equals(instance.vcpus.toString());
expect(estimates.cpu).to.equals(instance.cpu.toString());
};

let estimates_small = await deriveRenderedAwsEstimate("1.0000000", "9.0000000", "2048.0000000");

expect(estimates_small.name).to.equals("t2.small");
expect(estimates_small.cost).to.equals("0.00 USD");
assertAwsInstance(estimates_small);

let estimates_large = await deriveRenderedAwsEstimate("40.0000000", "18000.0000000", "194560.0000000");
expect(estimates_large.name).to.equals("m5d.12xlarge");
expect(estimates_large.cost).to.equals("16.32 USD");
assertAwsInstance(estimates_large);

let estimates_not_available = await deriveRenderedAwsEstimate(
"99999.0000000",
"18000.0000000",
"99999.0000000"
);
expect(estimates_not_available).to.equals(false);
});
});
14 changes: 10 additions & 4 deletions client/galaxy/scripts/components/JobMetrics/JobMetrics.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,18 @@
</table>
</div>

<div v-if="isAwsEstimate && awsEstimate">
<div id="aws-estimate" v-if="isAwsEstimate && awsEstimate">
<h3>AWS estimate</h3>
<b>{{ awsEstimate.price }} USD</b><br />
This job requested {{ awsEstimate.vcpus }} cores and {{ awsEstimate.memory }} Gb. Given this, the smallest
EC2 machine we could find is {{ awsEstimate.instance.name }} ({{ awsEstimate.instance.mem }} GB /
{{ awsEstimate.instance.vcpus }} vCPUs / {{ awsEstimate.instance.cpu }}). That instance is priced at
{{ awsEstimate.instance.price }} USD/hour.
EC2 machine we could find is <span id="aws_name">{{ awsEstimate.instance.name }}</span> (<span
id="aws_mem"
>{{ awsEstimate.instance.mem }}</span
>
GB / <span id="aws_vcpus">{{ awsEstimate.instance.vcpus }}</span> vCPUs /
<span id="aws_cpu">{{ awsEstimate.instance.cpu }}</span
>). That instance is priced at {{ awsEstimate.instance.price }} USD/hour.<br />
Please note, that those numbers are only estimates, all jobs are always free of charge for all users.
</div>
</div>
</template>
Expand Down Expand Up @@ -91,6 +96,7 @@ export default {
aws.instance = ec2.find((ec) => {
return ec.mem >= aws.memory && ec.vcpus >= aws.vcpus;
});
if (aws.instance === undefined) return;
aws.price = ((aws.seconds * aws.instance.price) / 3600).toFixed(2);
return aws;
},
Expand Down
4 changes: 3 additions & 1 deletion doc/source/admin/galaxy_options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1381,7 +1381,9 @@
~~~~~~~~~~~~~~~~

:Description:
Enable AWS estimate.
This flag enables an AWS cost estimate for every job based on their runtime matrices.
CPU, RAM and runtime usage is mapped against AWS pricing table.
Please note, that those numbers are only estimates.
:Default: ``false``
:Type: bool

Expand Down