[arvados-workbench2] updated: 2.6.0-107-g59342f2e
git repository hosting
git at public.arvados.org
Tue Sep 19 22:34:03 UTC 2023
Summary of changes:
cypress/integration/process.spec.js | 1616 ++++++++++----------
.../data-explorer/data-explorer.test.tsx | 138 +-
.../collection-service/collection-service.ts | 105 +-
.../action-sets/process-resource-action-set.ts | 34 +-
.../ms-collection-action-set.ts | 1 -
.../multiselect-toolbar/ms-process-action-set.ts | 4 +-
6 files changed, 938 insertions(+), 960 deletions(-)
via 59342f2ec8fe1ec2c7ba63a556b2003c23e687fe (commit)
from 778531e6b32ee2de9ca4a5f58e7c281330b8f2a4 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
commit 59342f2ec8fe1ec2c7ba63a556b2003c23e687fe
Author: Lisa Knox <lisaknox83 at gmail.com>
Date: Tue Sep 19 18:33:57 2023 -0400
15768: fixed rerun bug Arvados-DCO-1.1-Signed-off-by: Lisa Knox <lisa.knox at curii.com>
diff --git a/cypress/integration/process.spec.js b/cypress/integration/process.spec.js
index bdb4fae6..d6c9a606 100644
--- a/cypress/integration/process.spec.js
+++ b/cypress/integration/process.spec.js
@@ -2,28 +2,28 @@
//
// SPDX-License-Identifier: AGPL-3.0
-describe('Process tests', function() {
+describe("Process tests", function () {
let activeUser;
let adminUser;
- before(function() {
+ before(function () {
// Only set up common users once. These aren't set up as aliases because
// aliases are cleaned up after every test. Also it doesn't make sense
// to set the same users on beforeEach() over and over again, so we
// separate a little from Cypress' 'Best Practices' here.
- cy.getUser('admin', 'Admin', 'User', true, true)
- .as('adminUser').then(function() {
+ cy.getUser("admin", "Admin", "User", true, true)
+ .as("adminUser")
+ .then(function () {
adminUser = this.adminUser;
- }
- );
- cy.getUser('user', 'Active', 'User', false, true)
- .as('activeUser').then(function() {
+ });
+ cy.getUser("user", "Active", "User", false, true)
+ .as("activeUser")
+ .then(function () {
activeUser = this.activeUser;
- }
- );
+ });
});
- beforeEach(function() {
+ beforeEach(function () {
cy.clearCookies();
cy.clearLocalStorage();
});
@@ -31,42 +31,46 @@ describe('Process tests', function() {
function setupDockerImage(image_name) {
// Create a collection that will be used as a docker image for the tests.
cy.createCollection(adminUser.token, {
- name: 'docker_image',
- manifest_text: ". d21353cfe035e3e384563ee55eadbb2f+67108864 5c77a43e329b9838cbec18ff42790e57+55605760 0:122714624:sha256:d8309758b8fe2c81034ffc8a10c36460b77db7bc5e7b448c4e5b684f9d95a678.tar\n"
- }).as('dockerImage').then(function(dockerImage) {
- // Give read permissions to the active user on the docker image.
- cy.createLink(adminUser.token, {
- link_class: 'permission',
- name: 'can_read',
- tail_uuid: activeUser.user.uuid,
- head_uuid: dockerImage.uuid
- }).as('dockerImagePermission').then(function() {
- // Set-up docker image collection tags
- cy.createLink(activeUser.token, {
- link_class: 'docker_image_repo+tag',
- name: image_name,
- head_uuid: dockerImage.uuid,
- }).as('dockerImageRepoTag');
- cy.createLink(activeUser.token, {
- link_class: 'docker_image_hash',
- name: 'sha256:d8309758b8fe2c81034ffc8a10c36460b77db7bc5e7b448c4e5b684f9d95a678',
+ name: "docker_image",
+ manifest_text:
+ ". d21353cfe035e3e384563ee55eadbb2f+67108864 5c77a43e329b9838cbec18ff42790e57+55605760 0:122714624:sha256:d8309758b8fe2c81034ffc8a10c36460b77db7bc5e7b448c4e5b684f9d95a678.tar\n",
+ })
+ .as("dockerImage")
+ .then(function (dockerImage) {
+ // Give read permissions to the active user on the docker image.
+ cy.createLink(adminUser.token, {
+ link_class: "permission",
+ name: "can_read",
+ tail_uuid: activeUser.user.uuid,
head_uuid: dockerImage.uuid,
- }).as('dockerImageHash');
- })
- });
- return cy.getAll('@dockerImage', '@dockerImageRepoTag', '@dockerImageHash',
- '@dockerImagePermission').then(function([dockerImage]) {
- return dockerImage;
+ })
+ .as("dockerImagePermission")
+ .then(function () {
+ // Set-up docker image collection tags
+ cy.createLink(activeUser.token, {
+ link_class: "docker_image_repo+tag",
+ name: image_name,
+ head_uuid: dockerImage.uuid,
+ }).as("dockerImageRepoTag");
+ cy.createLink(activeUser.token, {
+ link_class: "docker_image_hash",
+ name: "sha256:d8309758b8fe2c81034ffc8a10c36460b77db7bc5e7b448c4e5b684f9d95a678",
+ head_uuid: dockerImage.uuid,
+ }).as("dockerImageHash");
+ });
});
+ return cy.getAll("@dockerImage", "@dockerImageRepoTag", "@dockerImageHash", "@dockerImagePermission").then(function ([dockerImage]) {
+ return dockerImage;
+ });
}
- function createContainerRequest(user, name, docker_image, command, reuse = false, state = 'Uncommitted') {
- return setupDockerImage(docker_image).then(function(dockerImage) {
+ function createContainerRequest(user, name, docker_image, command, reuse = false, state = "Uncommitted") {
+ return setupDockerImage(docker_image).then(function (dockerImage) {
return cy.createContainerRequest(user.token, {
name: name,
command: command,
container_image: dockerImage.portable_data_hash, // for some reason, docker_image doesn't work here
- output_path: 'stdout.txt',
+ output_path: "stdout.txt",
priority: 1,
runtime_constraints: {
vcpus: 1,
@@ -76,1104 +80,1075 @@ describe('Process tests', function() {
state: state,
mounts: {
foo: {
- kind: 'tmp',
- path: '/tmp/foo',
- }
- }
+ kind: "tmp",
+ path: "/tmp/foo",
+ },
+ },
});
});
}
- it('shows process logs', function() {
- const crName = 'test_container_request';
- createContainerRequest(
- activeUser,
- crName,
- 'arvados/jobs',
- ['echo', 'hello world'],
- false, 'Committed')
- .then(function(containerRequest) {
+ it("shows process logs", function () {
+ const crName = "test_container_request";
+ createContainerRequest(activeUser, crName, "arvados/jobs", ["echo", "hello world"], false, "Committed").then(function (containerRequest) {
cy.loginAs(activeUser);
cy.goToPath(`/processes/${containerRequest.uuid}`);
- cy.get('[data-cy=process-details]').should('contain', crName);
- cy.get('[data-cy=process-logs]')
- .should('contain', 'No logs yet')
- .and('not.contain', 'hello world');
+ cy.get("[data-cy=process-details]").should("contain", crName);
+ cy.get("[data-cy=process-logs]").should("contain", "No logs yet").and("not.contain", "hello world");
cy.createLog(activeUser.token, {
object_uuid: containerRequest.container_uuid,
properties: {
- text: 'hello world'
+ text: "hello world",
},
- event_type: 'stdout'
- }).then(function(log) {
- cy.get('[data-cy=process-logs]', {timeout: 7000})
- .should('not.contain', 'No logs yet')
- .and('contain', 'hello world');
- })
+ event_type: "stdout",
+ }).then(function (log) {
+ cy.get("[data-cy=process-logs]", { timeout: 7000 }).should("not.contain", "No logs yet").and("contain", "hello world");
+ });
});
});
- it('shows process details', function() {
+ it("shows process details", function () {
createContainerRequest(
activeUser,
`test_container_request ${Math.floor(Math.random() * 999999)}`,
- 'arvados/jobs',
- ['echo', 'hello world'],
- false, 'Committed')
- .then(function(containerRequest) {
+ "arvados/jobs",
+ ["echo", "hello world"],
+ false,
+ "Committed"
+ ).then(function (containerRequest) {
cy.loginAs(activeUser);
cy.goToPath(`/processes/${containerRequest.uuid}`);
- cy.get('[data-cy=process-details]').should('contain', containerRequest.name);
- cy.get('[data-cy=process-details-attributes-modifiedby-user]').contains(`Active User (${activeUser.user.uuid})`);
- cy.get('[data-cy=process-details-attributes-runtime-user]').should('not.exist');
+ cy.get("[data-cy=process-details]").should("contain", containerRequest.name);
+ cy.get("[data-cy=process-details-attributes-modifiedby-user]").contains(`Active User (${activeUser.user.uuid})`);
+ cy.get("[data-cy=process-details-attributes-runtime-user]").should("not.exist");
});
// Fake submitted by another user
- cy.intercept({method: 'GET', url: '**/arvados/v1/container_requests/*'}, (req) => {
- req.reply((res) => {
- res.body.modified_by_user_uuid = 'zzzzz-tpzed-000000000000000';
+ cy.intercept({ method: "GET", url: "**/arvados/v1/container_requests/*" }, req => {
+ req.reply(res => {
+ res.body.modified_by_user_uuid = "zzzzz-tpzed-000000000000000";
});
});
createContainerRequest(
activeUser,
`test_container_request ${Math.floor(Math.random() * 999999)}`,
- 'arvados/jobs',
- ['echo', 'hello world'],
- false, 'Committed')
- .then(function(containerRequest) {
+ "arvados/jobs",
+ ["echo", "hello world"],
+ false,
+ "Committed"
+ ).then(function (containerRequest) {
cy.loginAs(activeUser);
cy.goToPath(`/processes/${containerRequest.uuid}`);
- cy.get('[data-cy=process-details]').should('contain', containerRequest.name);
- cy.get('[data-cy=process-details-attributes-modifiedby-user]').contains(`zzzzz-tpzed-000000000000000`);
- cy.get('[data-cy=process-details-attributes-runtime-user]').contains(`Active User (${activeUser.user.uuid})`);
+ cy.get("[data-cy=process-details]").should("contain", containerRequest.name);
+ cy.get("[data-cy=process-details-attributes-modifiedby-user]").contains(`zzzzz-tpzed-000000000000000`);
+ cy.get("[data-cy=process-details-attributes-runtime-user]").contains(`Active User (${activeUser.user.uuid})`);
});
});
- it('filters process logs by event type', function() {
+ it("filters process logs by event type", function () {
const nodeInfoLogs = [
- 'Host Information',
- 'Linux compute-99cb150b26149780de44b929577e1aed-19rgca8vobuvc4p 5.4.0-1059-azure #62~18.04.1-Ubuntu SMP Tue Sep 14 17:53:18 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux',
- 'CPU Information',
- 'processor : 0',
- 'vendor_id : GenuineIntel',
- 'cpu family : 6',
- 'model : 79',
- 'model name : Intel(R) Xeon(R) CPU E5-2673 v4 @ 2.30GHz'
+ "Host Information",
+ "Linux compute-99cb150b26149780de44b929577e1aed-19rgca8vobuvc4p 5.4.0-1059-azure #62~18.04.1-Ubuntu SMP Tue Sep 14 17:53:18 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux",
+ "CPU Information",
+ "processor : 0",
+ "vendor_id : GenuineIntel",
+ "cpu family : 6",
+ "model : 79",
+ "model name : Intel(R) Xeon(R) CPU E5-2673 v4 @ 2.30GHz",
];
const crunchRunLogs = [
- '2022-03-22T13:56:22.542417997Z using local keepstore process (pid 3733) at http://localhost:46837, writing logs to keepstore.txt in log collection',
- '2022-03-22T13:56:26.237571754Z crunch-run 2.4.0~dev20220321141729 (go1.17.1) started',
- '2022-03-22T13:56:26.244704134Z crunch-run process has uid=0(root) gid=0(root) groups=0(root)',
- '2022-03-22T13:56:26.244862836Z Executing container \'zzzzz-dz642-1wokwvcct9s9du3\' using docker runtime',
- '2022-03-22T13:56:26.245037738Z Executing on host \'compute-99cb150b26149780de44b929577e1aed-19rgca8vobuvc4p\'',
+ "2022-03-22T13:56:22.542417997Z using local keepstore process (pid 3733) at http://localhost:46837, writing logs to keepstore.txt in log collection",
+ "2022-03-22T13:56:26.237571754Z crunch-run 2.4.0~dev20220321141729 (go1.17.1) started",
+ "2022-03-22T13:56:26.244704134Z crunch-run process has uid=0(root) gid=0(root) groups=0(root)",
+ "2022-03-22T13:56:26.244862836Z Executing container 'zzzzz-dz642-1wokwvcct9s9du3' using docker runtime",
+ "2022-03-22T13:56:26.245037738Z Executing on host 'compute-99cb150b26149780de44b929577e1aed-19rgca8vobuvc4p'",
];
const stdoutLogs = [
- 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec dui nisi, hendrerit porta sapien a, pretium dignissim purus.',
- 'Integer viverra, mauris finibus aliquet ultricies, dui mauris cursus justo, ut venenatis nibh ex eget neque.',
- 'In hac habitasse platea dictumst.',
- 'Fusce fringilla turpis id accumsan faucibus. Donec congue congue ex non posuere. In semper mi quis tristique rhoncus.',
- 'Interdum et malesuada fames ac ante ipsum primis in faucibus.',
- 'Quisque fermentum tortor ex, ut suscipit velit feugiat faucibus.',
- 'Donec vitae porta risus, at luctus nulla. Mauris gravida iaculis ipsum, id sagittis tortor egestas ac.',
- 'Maecenas condimentum volutpat nulla. Integer lacinia maximus risus eu posuere.',
- 'Donec vitae leo id augue gravida bibendum.',
- 'Nam libero libero, pretium ac faucibus elementum, mattis nec ex.',
- 'Nullam id laoreet nibh. Vivamus tellus metus, pretium quis justo ut, bibendum varius metus. Pellentesque vitae accumsan lorem, quis tincidunt augue.',
- 'Aliquam viverra nisi nulla, et efficitur dolor mattis in.',
- 'Sed at enim sit amet nulla tincidunt mattis. Aenean eget aliquet ex, non ultrices ex. Nulla ex tortor, vestibulum aliquam tempor ac, aliquam vel est.',
- 'Fusce auctor faucibus libero id venenatis. Etiam sodales, odio eu cursus efficitur, quam sem blandit ex, quis porttitor enim dui quis lectus. In id tincidunt felis.',
- 'Phasellus non ex quis arcu tempus faucibus molestie in sapien.',
- 'Duis tristique semper dolor, vitae pulvinar risus.',
- 'Aliquam tortor elit, luctus nec tortor eget, porta tristique nulla.',
- 'Nulla eget mollis ipsum.',
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec dui nisi, hendrerit porta sapien a, pretium dignissim purus.",
+ "Integer viverra, mauris finibus aliquet ultricies, dui mauris cursus justo, ut venenatis nibh ex eget neque.",
+ "In hac habitasse platea dictumst.",
+ "Fusce fringilla turpis id accumsan faucibus. Donec congue congue ex non posuere. In semper mi quis tristique rhoncus.",
+ "Interdum et malesuada fames ac ante ipsum primis in faucibus.",
+ "Quisque fermentum tortor ex, ut suscipit velit feugiat faucibus.",
+ "Donec vitae porta risus, at luctus nulla. Mauris gravida iaculis ipsum, id sagittis tortor egestas ac.",
+ "Maecenas condimentum volutpat nulla. Integer lacinia maximus risus eu posuere.",
+ "Donec vitae leo id augue gravida bibendum.",
+ "Nam libero libero, pretium ac faucibus elementum, mattis nec ex.",
+ "Nullam id laoreet nibh. Vivamus tellus metus, pretium quis justo ut, bibendum varius metus. Pellentesque vitae accumsan lorem, quis tincidunt augue.",
+ "Aliquam viverra nisi nulla, et efficitur dolor mattis in.",
+ "Sed at enim sit amet nulla tincidunt mattis. Aenean eget aliquet ex, non ultrices ex. Nulla ex tortor, vestibulum aliquam tempor ac, aliquam vel est.",
+ "Fusce auctor faucibus libero id venenatis. Etiam sodales, odio eu cursus efficitur, quam sem blandit ex, quis porttitor enim dui quis lectus. In id tincidunt felis.",
+ "Phasellus non ex quis arcu tempus faucibus molestie in sapien.",
+ "Duis tristique semper dolor, vitae pulvinar risus.",
+ "Aliquam tortor elit, luctus nec tortor eget, porta tristique nulla.",
+ "Nulla eget mollis ipsum.",
];
- createContainerRequest(
- activeUser,
- 'test_container_request',
- 'arvados/jobs',
- ['echo', 'hello world'],
- false, 'Committed')
- .then(function(containerRequest) {
- cy.logsForContainer(activeUser.token, containerRequest.container_uuid,
- 'node-info', nodeInfoLogs).as('nodeInfoLogs');
- cy.logsForContainer(activeUser.token, containerRequest.container_uuid,
- 'crunch-run', crunchRunLogs).as('crunchRunLogs');
- cy.logsForContainer(activeUser.token, containerRequest.container_uuid,
- 'stdout', stdoutLogs).as('stdoutLogs');
- cy.getAll('@stdoutLogs', '@nodeInfoLogs', '@crunchRunLogs').then(function() {
+ createContainerRequest(activeUser, "test_container_request", "arvados/jobs", ["echo", "hello world"], false, "Committed").then(function (
+ containerRequest
+ ) {
+ cy.logsForContainer(activeUser.token, containerRequest.container_uuid, "node-info", nodeInfoLogs).as("nodeInfoLogs");
+ cy.logsForContainer(activeUser.token, containerRequest.container_uuid, "crunch-run", crunchRunLogs).as("crunchRunLogs");
+ cy.logsForContainer(activeUser.token, containerRequest.container_uuid, "stdout", stdoutLogs).as("stdoutLogs");
+ cy.getAll("@stdoutLogs", "@nodeInfoLogs", "@crunchRunLogs").then(function () {
cy.loginAs(activeUser);
cy.goToPath(`/processes/${containerRequest.uuid}`);
// Should show main logs by default
- cy.get('[data-cy=process-logs-filter]', {timeout: 7000}).should('contain', 'Main logs');
- cy.get('[data-cy=process-logs]')
- .should('contain', stdoutLogs[Math.floor(Math.random() * stdoutLogs.length)])
- .and('not.contain', nodeInfoLogs[Math.floor(Math.random() * nodeInfoLogs.length)])
- .and('contain', crunchRunLogs[Math.floor(Math.random() * crunchRunLogs.length)]);
+ cy.get("[data-cy=process-logs-filter]", { timeout: 7000 }).should("contain", "Main logs");
+ cy.get("[data-cy=process-logs]")
+ .should("contain", stdoutLogs[Math.floor(Math.random() * stdoutLogs.length)])
+ .and("not.contain", nodeInfoLogs[Math.floor(Math.random() * nodeInfoLogs.length)])
+ .and("contain", crunchRunLogs[Math.floor(Math.random() * crunchRunLogs.length)]);
// Select 'All logs'
- cy.get('[data-cy=process-logs-filter]').click();
- cy.get('body').contains('li', 'All logs').click();
- cy.get('[data-cy=process-logs]')
- .should('contain', stdoutLogs[Math.floor(Math.random() * stdoutLogs.length)])
- .and('contain', nodeInfoLogs[Math.floor(Math.random() * nodeInfoLogs.length)])
- .and('contain', crunchRunLogs[Math.floor(Math.random() * crunchRunLogs.length)]);
+ cy.get("[data-cy=process-logs-filter]").click();
+ cy.get("body").contains("li", "All logs").click();
+ cy.get("[data-cy=process-logs]")
+ .should("contain", stdoutLogs[Math.floor(Math.random() * stdoutLogs.length)])
+ .and("contain", nodeInfoLogs[Math.floor(Math.random() * nodeInfoLogs.length)])
+ .and("contain", crunchRunLogs[Math.floor(Math.random() * crunchRunLogs.length)]);
// Select 'node-info' logs
- cy.get('[data-cy=process-logs-filter]').click();
- cy.get('body').contains('li', 'node-info').click();
- cy.get('[data-cy=process-logs]')
- .should('not.contain', stdoutLogs[Math.floor(Math.random() * stdoutLogs.length)])
- .and('contain', nodeInfoLogs[Math.floor(Math.random() * nodeInfoLogs.length)])
- .and('not.contain', crunchRunLogs[Math.floor(Math.random() * crunchRunLogs.length)]);
+ cy.get("[data-cy=process-logs-filter]").click();
+ cy.get("body").contains("li", "node-info").click();
+ cy.get("[data-cy=process-logs]")
+ .should("not.contain", stdoutLogs[Math.floor(Math.random() * stdoutLogs.length)])
+ .and("contain", nodeInfoLogs[Math.floor(Math.random() * nodeInfoLogs.length)])
+ .and("not.contain", crunchRunLogs[Math.floor(Math.random() * crunchRunLogs.length)]);
// Select 'stdout' logs
- cy.get('[data-cy=process-logs-filter]').click();
- cy.get('body').contains('li', 'stdout').click();
- cy.get('[data-cy=process-logs]')
- .should('contain', stdoutLogs[Math.floor(Math.random() * stdoutLogs.length)])
- .and('not.contain', nodeInfoLogs[Math.floor(Math.random() * nodeInfoLogs.length)])
- .and('not.contain', crunchRunLogs[Math.floor(Math.random() * crunchRunLogs.length)]);
+ cy.get("[data-cy=process-logs-filter]").click();
+ cy.get("body").contains("li", "stdout").click();
+ cy.get("[data-cy=process-logs]")
+ .should("contain", stdoutLogs[Math.floor(Math.random() * stdoutLogs.length)])
+ .and("not.contain", nodeInfoLogs[Math.floor(Math.random() * nodeInfoLogs.length)])
+ .and("not.contain", crunchRunLogs[Math.floor(Math.random() * crunchRunLogs.length)]);
});
});
});
- it('should show runtime status indicators', function() {
+ it("should show runtime status indicators", function () {
// Setup running container with runtime_status error & warning messages
- createContainerRequest(
- activeUser,
- 'test_container_request',
- 'arvados/jobs',
- ['echo', 'hello world'],
- false, 'Committed')
- .as('containerRequest')
- .then(function(containerRequest) {
- expect(containerRequest.state).to.equal('Committed');
- expect(containerRequest.container_uuid).not.to.be.equal('');
-
- cy.getContainer(activeUser.token, containerRequest.container_uuid)
- .then(function(queuedContainer) {
- expect(queuedContainer.state).to.be.equal('Queued');
- });
- cy.updateContainer(adminUser.token, containerRequest.container_uuid, {
- state: 'Locked'
- }).then(function(lockedContainer) {
- expect(lockedContainer.state).to.be.equal('Locked');
-
- cy.updateContainer(adminUser.token, lockedContainer.uuid, {
- state: 'Running',
- runtime_status: {
- error: 'Something went wrong',
- errorDetail: 'Process exited with status 1',
- warning: 'Free disk space is low',
- }
- })
- .as('runningContainer')
- .then(function(runningContainer) {
- expect(runningContainer.state).to.be.equal('Running');
- expect(runningContainer.runtime_status).to.be.deep.equal({
- 'error': 'Something went wrong',
- 'errorDetail': 'Process exited with status 1',
- 'warning': 'Free disk space is low',
- });
+ createContainerRequest(activeUser, "test_container_request", "arvados/jobs", ["echo", "hello world"], false, "Committed")
+ .as("containerRequest")
+ .then(function (containerRequest) {
+ expect(containerRequest.state).to.equal("Committed");
+ expect(containerRequest.container_uuid).not.to.be.equal("");
+
+ cy.getContainer(activeUser.token, containerRequest.container_uuid).then(function (queuedContainer) {
+ expect(queuedContainer.state).to.be.equal("Queued");
});
- })
- });
+ cy.updateContainer(adminUser.token, containerRequest.container_uuid, {
+ state: "Locked",
+ }).then(function (lockedContainer) {
+ expect(lockedContainer.state).to.be.equal("Locked");
+
+ cy.updateContainer(adminUser.token, lockedContainer.uuid, {
+ state: "Running",
+ runtime_status: {
+ error: "Something went wrong",
+ errorDetail: "Process exited with status 1",
+ warning: "Free disk space is low",
+ },
+ })
+ .as("runningContainer")
+ .then(function (runningContainer) {
+ expect(runningContainer.state).to.be.equal("Running");
+ expect(runningContainer.runtime_status).to.be.deep.equal({
+ error: "Something went wrong",
+ errorDetail: "Process exited with status 1",
+ warning: "Free disk space is low",
+ });
+ });
+ });
+ });
// Test that the UI shows the error and warning messages
- cy.getAll('@containerRequest', '@runningContainer').then(function([containerRequest]) {
+ cy.getAll("@containerRequest", "@runningContainer").then(function ([containerRequest]) {
cy.loginAs(activeUser);
cy.goToPath(`/processes/${containerRequest.uuid}`);
- cy.get('[data-cy=process-runtime-status-error]')
- .should('contain', 'Something went wrong')
- .and('contain', 'Process exited with status 1');
- cy.get('[data-cy=process-runtime-status-warning]')
- .should('contain', 'Free disk space is low')
- .and('contain', 'No additional warning details available');
+ cy.get("[data-cy=process-runtime-status-error]").should("contain", "Something went wrong").and("contain", "Process exited with status 1");
+ cy.get("[data-cy=process-runtime-status-warning]")
+ .should("contain", "Free disk space is low")
+ .and("contain", "No additional warning details available");
});
-
// Force container_count for testing
let containerCount = 2;
- cy.intercept({method: 'GET', url: '**/arvados/v1/container_requests/*'}, (req) => {
- req.reply((res) => {
+ cy.intercept({ method: "GET", url: "**/arvados/v1/container_requests/*" }, req => {
+ req.reply(res => {
res.body.container_count = containerCount;
});
});
- cy.getAll('@containerRequest').then(function([containerRequest]) {
+ cy.getAll("@containerRequest").then(function ([containerRequest]) {
cy.goToPath(`/processes/${containerRequest.uuid}`);
- cy.get('[data-cy=process-runtime-status-retry-warning]', {timeout: 7000})
- .should('contain', 'Process retried 1 time');
+ cy.get("[data-cy=process-runtime-status-retry-warning]", { timeout: 7000 }).should("contain", "Process retried 1 time");
});
- cy.getAll('@containerRequest').then(function([containerRequest]) {
+ cy.getAll("@containerRequest").then(function ([containerRequest]) {
containerCount = 3;
cy.goToPath(`/processes/${containerRequest.uuid}`);
- cy.get('[data-cy=process-runtime-status-retry-warning]', {timeout: 7000})
- .should('contain', 'Process retried 2 times');
+ cy.get("[data-cy=process-runtime-status-retry-warning]", { timeout: 7000 }).should("contain", "Process retried 2 times");
});
});
-
const testInputs = [
{
definition: {
- "id": "#main/input_file",
- "label": "Label Description",
- "type": "File"
+ id: "#main/input_file",
+ label: "Label Description",
+ type: "File",
},
input: {
- "input_file": {
- "basename": "input1.tar",
- "class": "File",
- "location": "keep:00000000000000000000000000000000+01/input1.tar",
- "secondaryFiles": [
+ input_file: {
+ basename: "input1.tar",
+ class: "File",
+ location: "keep:00000000000000000000000000000000+01/input1.tar",
+ secondaryFiles: [
{
- "basename": "input1-2.txt",
- "class": "File",
- "location": "keep:00000000000000000000000000000000+01/input1-2.txt"
+ basename: "input1-2.txt",
+ class: "File",
+ location: "keep:00000000000000000000000000000000+01/input1-2.txt",
},
{
- "basename": "input1-3.txt",
- "class": "File",
- "location": "keep:00000000000000000000000000000000+01/input1-3.txt"
+ basename: "input1-3.txt",
+ class: "File",
+ location: "keep:00000000000000000000000000000000+01/input1-3.txt",
},
{
- "basename": "input1-4.txt",
- "class": "File",
- "location": "keep:00000000000000000000000000000000+01/input1-4.txt"
- }
- ]
- }
- }
+ basename: "input1-4.txt",
+ class: "File",
+ location: "keep:00000000000000000000000000000000+01/input1-4.txt",
+ },
+ ],
+ },
+ },
},
{
definition: {
- "id": "#main/input_dir",
- "doc": "Doc Description",
- "type": "Directory"
+ id: "#main/input_dir",
+ doc: "Doc Description",
+ type: "Directory",
},
input: {
- "input_dir": {
- "basename": "11111111111111111111111111111111+01",
- "class": "Directory",
- "location": "keep:11111111111111111111111111111111+01"
- }
- }
+ input_dir: {
+ basename: "11111111111111111111111111111111+01",
+ class: "Directory",
+ location: "keep:11111111111111111111111111111111+01",
+ },
+ },
},
{
definition: {
- "id": "#main/input_bool",
- "doc": ["Doc desc 1", "Doc desc 2"],
- "type": "boolean"
+ id: "#main/input_bool",
+ doc: ["Doc desc 1", "Doc desc 2"],
+ type: "boolean",
},
input: {
- "input_bool": true,
- }
+ input_bool: true,
+ },
},
{
definition: {
- "id": "#main/input_int",
- "type": "int"
+ id: "#main/input_int",
+ type: "int",
},
input: {
- "input_int": 1,
- }
+ input_int: 1,
+ },
},
{
definition: {
- "id": "#main/input_long",
- "type": "long"
+ id: "#main/input_long",
+ type: "long",
},
input: {
- "input_long" : 1,
- }
+ input_long: 1,
+ },
},
{
definition: {
- "id": "#main/input_float",
- "type": "float"
+ id: "#main/input_float",
+ type: "float",
},
input: {
- "input_float": 1.5,
- }
+ input_float: 1.5,
+ },
},
{
definition: {
- "id": "#main/input_double",
- "type": "double"
+ id: "#main/input_double",
+ type: "double",
},
input: {
- "input_double": 1.3,
- }
+ input_double: 1.3,
+ },
},
{
definition: {
- "id": "#main/input_string",
- "type": "string"
+ id: "#main/input_string",
+ type: "string",
},
input: {
- "input_string": "Hello World",
- }
+ input_string: "Hello World",
+ },
},
{
definition: {
- "id": "#main/input_file_array",
- "type": {
- "items": "File",
- "type": "array"
- }
+ id: "#main/input_file_array",
+ type: {
+ items: "File",
+ type: "array",
+ },
},
input: {
- "input_file_array": [
+ input_file_array: [
{
- "basename": "input2.tar",
- "class": "File",
- "location": "keep:00000000000000000000000000000000+02/input2.tar"
+ basename: "input2.tar",
+ class: "File",
+ location: "keep:00000000000000000000000000000000+02/input2.tar",
},
{
- "basename": "input3.tar",
- "class": "File",
- "location": "keep:00000000000000000000000000000000+03/input3.tar",
- "secondaryFiles": [
+ basename: "input3.tar",
+ class: "File",
+ location: "keep:00000000000000000000000000000000+03/input3.tar",
+ secondaryFiles: [
{
- "basename": "input3-2.txt",
- "class": "File",
- "location": "keep:00000000000000000000000000000000+03/input3-2.txt"
- }
- ]
+ basename: "input3-2.txt",
+ class: "File",
+ location: "keep:00000000000000000000000000000000+03/input3-2.txt",
+ },
+ ],
},
{
- "$import": "import_path"
- }
- ]
- }
+ $import: "import_path",
+ },
+ ],
+ },
},
{
definition: {
- "id": "#main/input_dir_array",
- "type": {
- "items": "Directory",
- "type": "array"
- }
+ id: "#main/input_dir_array",
+ type: {
+ items: "Directory",
+ type: "array",
+ },
},
input: {
- "input_dir_array": [
+ input_dir_array: [
{
- "basename": "11111111111111111111111111111111+02",
- "class": "Directory",
- "location": "keep:11111111111111111111111111111111+02"
+ basename: "11111111111111111111111111111111+02",
+ class: "Directory",
+ location: "keep:11111111111111111111111111111111+02",
},
{
- "basename": "11111111111111111111111111111111+03",
- "class": "Directory",
- "location": "keep:11111111111111111111111111111111+03"
+ basename: "11111111111111111111111111111111+03",
+ class: "Directory",
+ location: "keep:11111111111111111111111111111111+03",
},
{
- "$import": "import_path"
- }
- ]
- }
+ $import: "import_path",
+ },
+ ],
+ },
},
{
definition: {
- "id": "#main/input_int_array",
- "type": {
- "items": "int",
- "type": "array"
- }
+ id: "#main/input_int_array",
+ type: {
+ items: "int",
+ type: "array",
+ },
},
input: {
- "input_int_array": [
+ input_int_array: [
1,
3,
5,
{
- "$import": "import_path"
- }
- ]
- }
+ $import: "import_path",
+ },
+ ],
+ },
},
{
definition: {
- "id": "#main/input_long_array",
- "type": {
- "items": "long",
- "type": "array"
- }
+ id: "#main/input_long_array",
+ type: {
+ items: "long",
+ type: "array",
+ },
},
input: {
- "input_long_array": [
+ input_long_array: [
10,
20,
{
- "$import": "import_path"
- }
- ]
- }
+ $import: "import_path",
+ },
+ ],
+ },
},
{
definition: {
- "id": "#main/input_float_array",
- "type": {
- "items": "float",
- "type": "array"
- }
+ id: "#main/input_float_array",
+ type: {
+ items: "float",
+ type: "array",
+ },
},
input: {
- "input_float_array": [
+ input_float_array: [
10.2,
10.4,
10.6,
{
- "$import": "import_path"
- }
- ]
- }
+ $import: "import_path",
+ },
+ ],
+ },
},
{
definition: {
- "id": "#main/input_double_array",
- "type": {
- "items": "double",
- "type": "array"
- }
+ id: "#main/input_double_array",
+ type: {
+ items: "double",
+ type: "array",
+ },
},
input: {
- "input_double_array": [
+ input_double_array: [
20.1,
20.2,
20.3,
{
- "$import": "import_path"
- }
- ]
- }
+ $import: "import_path",
+ },
+ ],
+ },
},
{
definition: {
- "id": "#main/input_string_array",
- "type": {
- "items": "string",
- "type": "array"
- }
+ id: "#main/input_string_array",
+ type: {
+ items: "string",
+ type: "array",
+ },
},
input: {
- "input_string_array": [
+ input_string_array: [
"Hello",
"World",
"!",
{
- "$import": "import_path"
- }
- ]
- }
+ $import: "import_path",
+ },
+ ],
+ },
},
{
definition: {
- "id": "#main/input_bool_include",
- "type": "boolean"
+ id: "#main/input_bool_include",
+ type: "boolean",
},
input: {
- "input_bool_include": {
- "$include": "include_path"
- }
- }
+ input_bool_include: {
+ $include: "include_path",
+ },
+ },
},
{
definition: {
- "id": "#main/input_int_include",
- "type": "int"
+ id: "#main/input_int_include",
+ type: "int",
},
input: {
- "input_int_include": {
- "$include": "include_path"
- }
- }
+ input_int_include: {
+ $include: "include_path",
+ },
+ },
},
{
definition: {
- "id": "#main/input_float_include",
- "type": "float"
+ id: "#main/input_float_include",
+ type: "float",
},
input: {
- "input_float_include": {
- "$include": "include_path"
- }
- }
+ input_float_include: {
+ $include: "include_path",
+ },
+ },
},
{
definition: {
- "id": "#main/input_string_include",
- "type": "string"
+ id: "#main/input_string_include",
+ type: "string",
},
input: {
- "input_string_include": {
- "$include": "include_path"
- }
- }
+ input_string_include: {
+ $include: "include_path",
+ },
+ },
},
{
definition: {
- "id": "#main/input_file_include",
- "type": "File"
+ id: "#main/input_file_include",
+ type: "File",
},
input: {
- "input_file_include": {
- "$include": "include_path"
- }
- }
+ input_file_include: {
+ $include: "include_path",
+ },
+ },
},
{
definition: {
- "id": "#main/input_directory_include",
- "type": "Directory"
+ id: "#main/input_directory_include",
+ type: "Directory",
},
input: {
- "input_directory_include": {
- "$include": "include_path"
- }
- }
+ input_directory_include: {
+ $include: "include_path",
+ },
+ },
},
{
definition: {
- "id": "#main/input_file_url",
- "type": "File"
+ id: "#main/input_file_url",
+ type: "File",
},
input: {
- "input_file_url": {
- "basename": "index.html",
- "class": "File",
- "location": "http://example.com/index.html"
- }
- }
- }
+ input_file_url: {
+ basename: "index.html",
+ class: "File",
+ location: "http://example.com/index.html",
+ },
+ },
+ },
];
const testOutputs = [
{
definition: {
- "id": "#main/output_file",
- "label": "Label Description",
- "type": "File"
+ id: "#main/output_file",
+ label: "Label Description",
+ type: "File",
},
output: {
- "output_file": {
- "basename": "cat.png",
- "class": "File",
- "location": "cat.png"
- }
- }
+ output_file: {
+ basename: "cat.png",
+ class: "File",
+ location: "cat.png",
+ },
+ },
},
{
definition: {
- "id": "#main/output_file_with_secondary",
- "doc": "Doc Description",
- "type": "File"
+ id: "#main/output_file_with_secondary",
+ doc: "Doc Description",
+ type: "File",
},
output: {
- "output_file_with_secondary": {
- "basename": "main.dat",
- "class": "File",
- "location": "main.dat",
- "secondaryFiles": [
+ output_file_with_secondary: {
+ basename: "main.dat",
+ class: "File",
+ location: "main.dat",
+ secondaryFiles: [
{
- "basename": "secondary.dat",
- "class": "File",
- "location": "secondary.dat"
+ basename: "secondary.dat",
+ class: "File",
+ location: "secondary.dat",
},
{
- "basename": "secondary2.dat",
- "class": "File",
- "location": "secondary2.dat"
- }
- ]
- }
- }
+ basename: "secondary2.dat",
+ class: "File",
+ location: "secondary2.dat",
+ },
+ ],
+ },
+ },
},
{
definition: {
- "id": "#main/output_dir",
- "doc": ["Doc desc 1", "Doc desc 2"],
- "type": "Directory"
+ id: "#main/output_dir",
+ doc: ["Doc desc 1", "Doc desc 2"],
+ type: "Directory",
},
output: {
- "output_dir": {
- "basename": "outdir1",
- "class": "Directory",
- "location": "outdir1"
- }
- }
+ output_dir: {
+ basename: "outdir1",
+ class: "Directory",
+ location: "outdir1",
+ },
+ },
},
{
definition: {
- "id": "#main/output_bool",
- "type": "boolean"
+ id: "#main/output_bool",
+ type: "boolean",
},
output: {
- "output_bool": true
- }
+ output_bool: true,
+ },
},
{
definition: {
- "id": "#main/output_int",
- "type": "int"
+ id: "#main/output_int",
+ type: "int",
},
output: {
- "output_int": 1
- }
+ output_int: 1,
+ },
},
{
definition: {
- "id": "#main/output_long",
- "type": "long"
+ id: "#main/output_long",
+ type: "long",
},
output: {
- "output_long": 1
- }
+ output_long: 1,
+ },
},
{
definition: {
- "id": "#main/output_float",
- "type": "float"
+ id: "#main/output_float",
+ type: "float",
},
output: {
- "output_float": 100.5
- }
+ output_float: 100.5,
+ },
},
{
definition: {
- "id": "#main/output_double",
- "type": "double"
+ id: "#main/output_double",
+ type: "double",
},
output: {
- "output_double": 100.3
- }
+ output_double: 100.3,
+ },
},
{
definition: {
- "id": "#main/output_string",
- "type": "string"
+ id: "#main/output_string",
+ type: "string",
},
output: {
- "output_string": "Hello output"
- }
+ output_string: "Hello output",
+ },
},
{
definition: {
- "id": "#main/output_file_array",
- "type": {
- "items": "File",
- "type": "array"
- }
+ id: "#main/output_file_array",
+ type: {
+ items: "File",
+ type: "array",
+ },
},
output: {
- "output_file_array": [
+ output_file_array: [
{
- "basename": "output2.tar",
- "class": "File",
- "location": "output2.tar"
+ basename: "output2.tar",
+ class: "File",
+ location: "output2.tar",
},
{
- "basename": "output3.tar",
- "class": "File",
- "location": "output3.tar"
- }
- ]
- }
+ basename: "output3.tar",
+ class: "File",
+ location: "output3.tar",
+ },
+ ],
+ },
},
{
definition: {
- "id": "#main/output_dir_array",
- "type": {
- "items": "Directory",
- "type": "array"
- }
+ id: "#main/output_dir_array",
+ type: {
+ items: "Directory",
+ type: "array",
+ },
},
output: {
- "output_dir_array": [
+ output_dir_array: [
{
- "basename": "outdir2",
- "class": "Directory",
- "location": "outdir2"
+ basename: "outdir2",
+ class: "Directory",
+ location: "outdir2",
},
{
- "basename": "outdir3",
- "class": "Directory",
- "location": "outdir3"
- }
- ]
- }
+ basename: "outdir3",
+ class: "Directory",
+ location: "outdir3",
+ },
+ ],
+ },
},
{
definition: {
- "id": "#main/output_int_array",
- "type": {
- "items": "int",
- "type": "array"
- }
+ id: "#main/output_int_array",
+ type: {
+ items: "int",
+ type: "array",
+ },
},
output: {
- "output_int_array": [
- 10,
- 11,
- 12
- ]
- }
+ output_int_array: [10, 11, 12],
+ },
},
{
definition: {
- "id": "#main/output_long_array",
- "type": {
- "items": "long",
- "type": "array"
- }
+ id: "#main/output_long_array",
+ type: {
+ items: "long",
+ type: "array",
+ },
},
output: {
- "output_long_array": [
- 51,
- 52
- ]
- }
+ output_long_array: [51, 52],
+ },
},
{
definition: {
- "id": "#main/output_float_array",
- "type": {
- "items": "float",
- "type": "array"
- }
+ id: "#main/output_float_array",
+ type: {
+ items: "float",
+ type: "array",
+ },
},
output: {
- "output_float_array": [
- 100.2,
- 100.4,
- 100.6
- ]
- }
+ output_float_array: [100.2, 100.4, 100.6],
+ },
},
{
definition: {
- "id": "#main/output_double_array",
- "type": {
- "items": "double",
- "type": "array"
- }
+ id: "#main/output_double_array",
+ type: {
+ items: "double",
+ type: "array",
+ },
},
output: {
- "output_double_array": [
- 100.1,
- 100.2,
- 100.3
- ]
- }
+ output_double_array: [100.1, 100.2, 100.3],
+ },
},
{
definition: {
- "id": "#main/output_string_array",
- "type": {
- "items": "string",
- "type": "array"
- }
+ id: "#main/output_string_array",
+ type: {
+ items: "string",
+ type: "array",
+ },
},
output: {
- "output_string_array": [
- "Hello",
- "Output",
- "!"
- ]
- }
- }
+ output_string_array: ["Hello", "Output", "!"],
+ },
+ },
];
const verifyIOParameter = (name, label, doc, val, collection, multipleRows) => {
- cy.get('table tr').contains(name).parents('tr').within(($mainRow) => {
- label && cy.contains(label);
-
- if (multipleRows) {
- cy.get($mainRow).nextUntil('[data-cy="process-io-param"]').as('secondaryRows');
- if (val) {
- if (Array.isArray(val)) {
- val.forEach(v => cy.get('@secondaryRows').contains(v));
- } else {
- cy.get('@secondaryRows').contains(val);
+ cy.get("table tr")
+ .contains(name)
+ .parents("tr")
+ .within($mainRow => {
+ label && cy.contains(label);
+
+ if (multipleRows) {
+ cy.get($mainRow).nextUntil('[data-cy="process-io-param"]').as("secondaryRows");
+ if (val) {
+ if (Array.isArray(val)) {
+ val.forEach(v => cy.get("@secondaryRows").contains(v));
+ } else {
+ cy.get("@secondaryRows").contains(val);
+ }
}
- }
- if (collection) {
- cy.get('@secondaryRows').contains(collection);
- }
- } else {
- if (val) {
- if (Array.isArray(val)) {
- val.forEach(v => cy.contains(v));
- } else {
- cy.contains(val);
+ if (collection) {
+ cy.get("@secondaryRows").contains(collection);
+ }
+ } else {
+ if (val) {
+ if (Array.isArray(val)) {
+ val.forEach(v => cy.contains(v));
+ } else {
+ cy.contains(val);
+ }
+ }
+ if (collection) {
+ cy.contains(collection);
}
}
- if (collection) {
- cy.contains(collection);
- }
- }
-
-
- });
+ });
};
const verifyIOParameterImage = (name, url) => {
- cy.get('table tr').contains(name).parents('tr').within(() => {
- cy.get('[alt="Inline Preview"]')
- .should('be.visible')
- .and(($img) => {
- expect($img[0].naturalWidth).to.be.greaterThan(0);
- expect($img[0].src).contains(url);
- })
- });
+ cy.get("table tr")
+ .contains(name)
+ .parents("tr")
+ .within(() => {
+ cy.get('[alt="Inline Preview"]')
+ .should("be.visible")
+ .and($img => {
+ expect($img[0].naturalWidth).to.be.greaterThan(0);
+ expect($img[0].src).contains(url);
+ });
+ });
};
- it('displays IO parameters with keep links and previews', function() {
+ it("displays IO parameters with keep links and previews", function () {
// Create output collection for real files
cy.createCollection(adminUser.token, {
name: `Test collection ${Math.floor(Math.random() * 999999)}`,
owner_uuid: activeUser.user.uuid,
- }).then((testOutputCollection) => {
- cy.loginAs(activeUser);
+ }).then(testOutputCollection => {
+ cy.loginAs(activeUser);
- cy.goToPath(`/collections/${testOutputCollection.uuid}`);
+ cy.goToPath(`/collections/${testOutputCollection.uuid}`);
- cy.get('[data-cy=upload-button]').click();
+ cy.get("[data-cy=upload-button]").click();
- cy.fixture('files/cat.png', 'base64').then(content => {
- cy.get('[data-cy=drag-and-drop]').upload(content, 'cat.png');
- cy.get('[data-cy=form-submit-btn]').click();
- cy.waitForDom().get('[data-cy=form-submit-btn]').should('not.exist');
- // Confirm final collection state.
- cy.get('[data-cy=collection-files-panel]')
- .contains('cat.png').should('exist');
- });
+ cy.fixture("files/cat.png", "base64").then(content => {
+ cy.get("[data-cy=drag-and-drop]").upload(content, "cat.png");
+ cy.get("[data-cy=form-submit-btn]").click();
+ cy.waitForDom().get("[data-cy=form-submit-btn]").should("not.exist");
+ // Confirm final collection state.
+ cy.get("[data-cy=collection-files-panel]").contains("cat.png").should("exist");
+ });
- cy.getCollection(activeUser.token, testOutputCollection.uuid).as('testOutputCollection');
- });
+ cy.getCollection(activeUser.token, testOutputCollection.uuid).as("testOutputCollection");
+ });
// Get updated collection pdh
- cy.getAll('@testOutputCollection').then(([testOutputCollection]) => {
+ cy.getAll("@testOutputCollection").then(([testOutputCollection]) => {
// Add output uuid and inputs to container request
- cy.intercept({method: 'GET', url: '**/arvados/v1/container_requests/*'}, (req) => {
- req.reply((res) => {
+ cy.intercept({ method: "GET", url: "**/arvados/v1/container_requests/*" }, req => {
+ req.reply(res => {
res.body.output_uuid = testOutputCollection.uuid;
res.body.mounts["/var/lib/cwl/cwl.input.json"] = {
- content: testInputs.map((param) => (param.input)).reduce((acc, val) => (Object.assign(acc, val)), {})
+ content: testInputs.map(param => param.input).reduce((acc, val) => Object.assign(acc, val), {}),
};
res.body.mounts["/var/lib/cwl/workflow.json"] = {
content: {
- $graph: [{
- id: "#main",
- inputs: testInputs.map((input) => (input.definition)),
- outputs: testOutputs.map((output) => (output.definition))
- }]
- }
+ $graph: [
+ {
+ id: "#main",
+ inputs: testInputs.map(input => input.definition),
+ outputs: testOutputs.map(output => output.definition),
+ },
+ ],
+ },
};
});
});
// Stub fake output collection
- cy.intercept({method: 'GET', url: `**/arvados/v1/collections/${testOutputCollection.uuid}*`}, {
- statusCode: 200,
- body: {
- uuid: testOutputCollection.uuid,
- portable_data_hash: testOutputCollection.portable_data_hash,
+ cy.intercept(
+ { method: "GET", url: `**/arvados/v1/collections/${testOutputCollection.uuid}*` },
+ {
+ statusCode: 200,
+ body: {
+ uuid: testOutputCollection.uuid,
+ portable_data_hash: testOutputCollection.portable_data_hash,
+ },
}
- });
+ );
// Stub fake output json
- cy.intercept({method: 'GET', url: '**/c%3Dzzzzz-4zz18-zzzzzzzzzzzzzzz/cwl.output.json'}, {
- statusCode: 200,
- body: testOutputs.map((param) => (param.output)).reduce((acc, val) => (Object.assign(acc, val)), {})
- });
+ cy.intercept(
+ { method: "GET", url: "**/c%3Dzzzzz-4zz18-zzzzzzzzzzzzzzz/cwl.output.json" },
+ {
+ statusCode: 200,
+ body: testOutputs.map(param => param.output).reduce((acc, val) => Object.assign(acc, val), {}),
+ }
+ );
// Stub webdav response, points to output json
- cy.intercept({method: 'PROPFIND', url: '*'}, {
- fixture: 'webdav-propfind-outputs.xml',
- });
+ cy.intercept(
+ { method: "PROPFIND", url: "*" },
+ {
+ fixture: "webdav-propfind-outputs.xml",
+ }
+ );
});
- createContainerRequest(
- activeUser,
- 'test_container_request',
- 'arvados/jobs',
- ['echo', 'hello world'],
- false, 'Committed')
- .as('containerRequest');
+ createContainerRequest(activeUser, "test_container_request", "arvados/jobs", ["echo", "hello world"], false, "Committed").as(
+ "containerRequest"
+ );
- cy.getAll('@containerRequest', '@testOutputCollection').then(function([containerRequest, testOutputCollection]) {
+ cy.getAll("@containerRequest", "@testOutputCollection").then(function ([containerRequest, testOutputCollection]) {
cy.goToPath(`/processes/${containerRequest.uuid}`);
- cy.get('[data-cy=process-io-card] h6').contains('Inputs')
- .parents('[data-cy=process-io-card]').within(() => {
- verifyIOParameter('input_file', null, "Label Description", 'input1.tar', '00000000000000000000000000000000+01');
- verifyIOParameter('input_file', null, "Label Description", 'input1-2.txt', undefined, true);
- verifyIOParameter('input_file', null, "Label Description", 'input1-3.txt', undefined, true);
- verifyIOParameter('input_file', null, "Label Description", 'input1-4.txt', undefined, true);
- verifyIOParameter('input_dir', null, "Doc Description", '/', '11111111111111111111111111111111+01');
- verifyIOParameter('input_bool', null, "Doc desc 1, Doc desc 2", 'true');
- verifyIOParameter('input_int', null, null, '1');
- verifyIOParameter('input_long', null, null, '1');
- verifyIOParameter('input_float', null, null, '1.5');
- verifyIOParameter('input_double', null, null, '1.3');
- verifyIOParameter('input_string', null, null, 'Hello World');
- verifyIOParameter('input_file_array', null, null, 'input2.tar', '00000000000000000000000000000000+02');
- verifyIOParameter('input_file_array', null, null, 'input3.tar', undefined, true);
- verifyIOParameter('input_file_array', null, null, 'input3-2.txt', undefined, true);
- verifyIOParameter('input_file_array', null, null, 'Cannot display value', undefined, true);
- verifyIOParameter('input_dir_array', null, null, '/', '11111111111111111111111111111111+02');
- verifyIOParameter('input_dir_array', null, null, '/', '11111111111111111111111111111111+03', true);
- verifyIOParameter('input_dir_array', null, null, 'Cannot display value', undefined, true);
- verifyIOParameter('input_int_array', null, null, ["1", "3", "5", "Cannot display value"]);
- verifyIOParameter('input_long_array', null, null, ["10", "20", "Cannot display value"]);
- verifyIOParameter('input_float_array', null, null, ["10.2", "10.4", "10.6", "Cannot display value"]);
- verifyIOParameter('input_double_array', null, null, ["20.1", "20.2", "20.3", "Cannot display value"]);
- verifyIOParameter('input_string_array', null, null, ["Hello", "World", "!", "Cannot display value"]);
- verifyIOParameter('input_bool_include', null, null, "Cannot display value");
- verifyIOParameter('input_int_include', null, null, "Cannot display value");
- verifyIOParameter('input_float_include', null, null, "Cannot display value");
- verifyIOParameter('input_string_include', null, null, "Cannot display value");
- verifyIOParameter('input_file_include', null, null, "Cannot display value");
- verifyIOParameter('input_directory_include', null, null, "Cannot display value");
- verifyIOParameter('input_file_url', null, null, "http://example.com/index.html");
+ cy.get("[data-cy=process-io-card] h6")
+ .contains("Inputs")
+ .parents("[data-cy=process-io-card]")
+ .within(() => {
+ verifyIOParameter("input_file", null, "Label Description", "input1.tar", "00000000000000000000000000000000+01");
+ verifyIOParameter("input_file", null, "Label Description", "input1-2.txt", undefined, true);
+ verifyIOParameter("input_file", null, "Label Description", "input1-3.txt", undefined, true);
+ verifyIOParameter("input_file", null, "Label Description", "input1-4.txt", undefined, true);
+ verifyIOParameter("input_dir", null, "Doc Description", "/", "11111111111111111111111111111111+01");
+ verifyIOParameter("input_bool", null, "Doc desc 1, Doc desc 2", "true");
+ verifyIOParameter("input_int", null, null, "1");
+ verifyIOParameter("input_long", null, null, "1");
+ verifyIOParameter("input_float", null, null, "1.5");
+ verifyIOParameter("input_double", null, null, "1.3");
+ verifyIOParameter("input_string", null, null, "Hello World");
+ verifyIOParameter("input_file_array", null, null, "input2.tar", "00000000000000000000000000000000+02");
+ verifyIOParameter("input_file_array", null, null, "input3.tar", undefined, true);
+ verifyIOParameter("input_file_array", null, null, "input3-2.txt", undefined, true);
+ verifyIOParameter("input_file_array", null, null, "Cannot display value", undefined, true);
+ verifyIOParameter("input_dir_array", null, null, "/", "11111111111111111111111111111111+02");
+ verifyIOParameter("input_dir_array", null, null, "/", "11111111111111111111111111111111+03", true);
+ verifyIOParameter("input_dir_array", null, null, "Cannot display value", undefined, true);
+ verifyIOParameter("input_int_array", null, null, ["1", "3", "5", "Cannot display value"]);
+ verifyIOParameter("input_long_array", null, null, ["10", "20", "Cannot display value"]);
+ verifyIOParameter("input_float_array", null, null, ["10.2", "10.4", "10.6", "Cannot display value"]);
+ verifyIOParameter("input_double_array", null, null, ["20.1", "20.2", "20.3", "Cannot display value"]);
+ verifyIOParameter("input_string_array", null, null, ["Hello", "World", "!", "Cannot display value"]);
+ verifyIOParameter("input_bool_include", null, null, "Cannot display value");
+ verifyIOParameter("input_int_include", null, null, "Cannot display value");
+ verifyIOParameter("input_float_include", null, null, "Cannot display value");
+ verifyIOParameter("input_string_include", null, null, "Cannot display value");
+ verifyIOParameter("input_file_include", null, null, "Cannot display value");
+ verifyIOParameter("input_directory_include", null, null, "Cannot display value");
+ verifyIOParameter("input_file_url", null, null, "http://example.com/index.html");
});
- cy.get('[data-cy=process-io-card] h6').contains('Outputs')
- .parents('[data-cy=process-io-card]').within((ctx) => {
+ cy.get("[data-cy=process-io-card] h6")
+ .contains("Outputs")
+ .parents("[data-cy=process-io-card]")
+ .within(ctx => {
cy.get(ctx).scrollIntoView();
- cy.get('[data-cy="io-preview-image-toggle"]').click({waitForAnimations: false});
+ cy.get('[data-cy="io-preview-image-toggle"]').click({ waitForAnimations: false });
const outPdh = testOutputCollection.portable_data_hash;
- verifyIOParameter('output_file', null, "Label Description", 'cat.png', `${outPdh}`);
- verifyIOParameterImage('output_file', `/c=${outPdh}/cat.png`);
- verifyIOParameter('output_file_with_secondary', null, "Doc Description", 'main.dat', `${outPdh}`);
- verifyIOParameter('output_file_with_secondary', null, "Doc Description", 'secondary.dat', undefined, true);
- verifyIOParameter('output_file_with_secondary', null, "Doc Description", 'secondary2.dat', undefined, true);
- verifyIOParameter('output_dir', null, "Doc desc 1, Doc desc 2", 'outdir1', `${outPdh}`);
- verifyIOParameter('output_bool', null, null, 'true');
- verifyIOParameter('output_int', null, null, '1');
- verifyIOParameter('output_long', null, null, '1');
- verifyIOParameter('output_float', null, null, '100.5');
- verifyIOParameter('output_double', null, null, '100.3');
- verifyIOParameter('output_string', null, null, 'Hello output');
- verifyIOParameter('output_file_array', null, null, 'output2.tar', `${outPdh}`);
- verifyIOParameter('output_file_array', null, null, 'output3.tar', undefined, true);
- verifyIOParameter('output_dir_array', null, null, 'outdir2', `${outPdh}`);
- verifyIOParameter('output_dir_array', null, null, 'outdir3', undefined, true);
- verifyIOParameter('output_int_array', null, null, ["10", "11", "12"]);
- verifyIOParameter('output_long_array', null, null, ["51", "52"]);
- verifyIOParameter('output_float_array', null, null, ["100.2", "100.4", "100.6"]);
- verifyIOParameter('output_double_array', null, null, ["100.1", "100.2", "100.3"]);
- verifyIOParameter('output_string_array', null, null, ["Hello", "Output", "!"]);
+ verifyIOParameter("output_file", null, "Label Description", "cat.png", `${outPdh}`);
+ verifyIOParameterImage("output_file", `/c=${outPdh}/cat.png`);
+ verifyIOParameter("output_file_with_secondary", null, "Doc Description", "main.dat", `${outPdh}`);
+ verifyIOParameter("output_file_with_secondary", null, "Doc Description", "secondary.dat", undefined, true);
+ verifyIOParameter("output_file_with_secondary", null, "Doc Description", "secondary2.dat", undefined, true);
+ verifyIOParameter("output_dir", null, "Doc desc 1, Doc desc 2", "outdir1", `${outPdh}`);
+ verifyIOParameter("output_bool", null, null, "true");
+ verifyIOParameter("output_int", null, null, "1");
+ verifyIOParameter("output_long", null, null, "1");
+ verifyIOParameter("output_float", null, null, "100.5");
+ verifyIOParameter("output_double", null, null, "100.3");
+ verifyIOParameter("output_string", null, null, "Hello output");
+ verifyIOParameter("output_file_array", null, null, "output2.tar", `${outPdh}`);
+ verifyIOParameter("output_file_array", null, null, "output3.tar", undefined, true);
+ verifyIOParameter("output_dir_array", null, null, "outdir2", `${outPdh}`);
+ verifyIOParameter("output_dir_array", null, null, "outdir3", undefined, true);
+ verifyIOParameter("output_int_array", null, null, ["10", "11", "12"]);
+ verifyIOParameter("output_long_array", null, null, ["51", "52"]);
+ verifyIOParameter("output_float_array", null, null, ["100.2", "100.4", "100.6"]);
+ verifyIOParameter("output_double_array", null, null, ["100.1", "100.2", "100.3"]);
+ verifyIOParameter("output_string_array", null, null, ["Hello", "Output", "!"]);
});
});
});
- it('displays IO parameters with no value', function() {
-
- const fakeOutputUUID = 'zzzzz-4zz18-abcdefghijklmno';
- const fakeOutputPDH = '11111111111111111111111111111111+99/';
+ it("displays IO parameters with no value", function () {
+ const fakeOutputUUID = "zzzzz-4zz18-abcdefghijklmno";
+ const fakeOutputPDH = "11111111111111111111111111111111+99/";
cy.loginAs(activeUser);
// Add output uuid and inputs to container request
- cy.intercept({method: 'GET', url: '**/arvados/v1/container_requests/*'}, (req) => {
- req.reply((res) => {
+ cy.intercept({ method: "GET", url: "**/arvados/v1/container_requests/*" }, req => {
+ req.reply(res => {
res.body.output_uuid = fakeOutputUUID;
res.body.mounts["/var/lib/cwl/cwl.input.json"] = {
- content: {}
+ content: {},
};
res.body.mounts["/var/lib/cwl/workflow.json"] = {
content: {
- $graph: [{
- id: "#main",
- inputs: testInputs.map((input) => (input.definition)),
- outputs: testOutputs.map((output) => (output.definition))
- }]
- }
+ $graph: [
+ {
+ id: "#main",
+ inputs: testInputs.map(input => input.definition),
+ outputs: testOutputs.map(output => output.definition),
+ },
+ ],
+ },
};
});
});
// Stub fake output collection
- cy.intercept({method: 'GET', url: `**/arvados/v1/collections/${fakeOutputUUID}*`}, {
- statusCode: 200,
- body: {
- uuid: fakeOutputUUID,
- portable_data_hash: fakeOutputPDH,
+ cy.intercept(
+ { method: "GET", url: `**/arvados/v1/collections/${fakeOutputUUID}*` },
+ {
+ statusCode: 200,
+ body: {
+ uuid: fakeOutputUUID,
+ portable_data_hash: fakeOutputPDH,
+ },
}
- });
+ );
// Stub fake output json
- cy.intercept({method: 'GET', url: `**/c%3D${fakeOutputUUID}/cwl.output.json`}, {
- statusCode: 200,
- body: {}
- });
+ cy.intercept(
+ { method: "GET", url: `**/c%3D${fakeOutputUUID}/cwl.output.json` },
+ {
+ statusCode: 200,
+ body: {},
+ }
+ );
- cy.readFile('cypress/fixtures/webdav-propfind-outputs.xml').then((data) => {
+ cy.readFile("cypress/fixtures/webdav-propfind-outputs.xml").then(data => {
// Stub webdav response, points to output json
- cy.intercept({method: 'PROPFIND', url: '*'}, {
- statusCode: 200,
- body: data.replace(/zzzzz-4zz18-zzzzzzzzzzzzzzz/g, fakeOutputUUID)
- });
+ cy.intercept(
+ { method: "PROPFIND", url: "*" },
+ {
+ statusCode: 200,
+ body: data.replace(/zzzzz-4zz18-zzzzzzzzzzzzzzz/g, fakeOutputUUID),
+ }
+ );
});
- createContainerRequest(
- activeUser,
- 'test_container_request',
- 'arvados/jobs',
- ['echo', 'hello world'],
- false, 'Committed')
- .as('containerRequest');
+ createContainerRequest(activeUser, "test_container_request", "arvados/jobs", ["echo", "hello world"], false, "Committed").as(
+ "containerRequest"
+ );
- cy.getAll('@containerRequest').then(function([containerRequest]) {
+ cy.getAll("@containerRequest").then(function ([containerRequest]) {
cy.goToPath(`/processes/${containerRequest.uuid}`);
- cy.get('[data-cy=process-io-card] h6').contains('Inputs')
- .parents('[data-cy=process-io-card]').within(() => {
+ cy.get("[data-cy=process-io-card] h6")
+ .contains("Inputs")
+ .parents("[data-cy=process-io-card]")
+ .within(() => {
cy.wait(2000);
cy.waitForDom();
- cy.get('tbody tr').each((item) => {
- cy.wrap(item).contains('No value');
+ cy.get("tbody tr").each(item => {
+ cy.wrap(item).contains("No value");
});
});
- cy.get('[data-cy=process-io-card] h6').contains('Outputs')
- .parents('[data-cy=process-io-card]').within(() => {
- cy.get('tbody tr').each((item) => {
- cy.wrap(item).contains('No value');
+ cy.get("[data-cy=process-io-card] h6")
+ .contains("Outputs")
+ .parents("[data-cy=process-io-card]")
+ .within(() => {
+ cy.get("tbody tr").each(item => {
+ cy.wrap(item).contains("No value");
});
});
});
});
-
- it('allows copying processes', function() {
- const crName = 'first_container_request';
- const copiedCrName = 'copied_container_request';
- createContainerRequest(
- activeUser,
- crName,
- 'arvados/jobs',
- ['echo', 'hello world'],
- false, 'Committed')
- .then(function(containerRequest) {
+ it("allows copying processes", function () {
+ const crName = "first_container_request";
+ const copiedCrName = "copied_container_request";
+ createContainerRequest(activeUser, crName, "arvados/jobs", ["echo", "hello world"], false, "Committed").then(function (containerRequest) {
cy.loginAs(activeUser);
cy.goToPath(`/processes/${containerRequest.uuid}`);
- cy.get('[data-cy=process-details]').should('contain', crName);
+ cy.get("[data-cy=process-details]").should("contain", crName);
- cy.get('[data-cy=process-details]').find('button[title="More options"]').click();
- cy.get('ul[data-cy=context-menu]').contains("Copy and re-run process").click();
+ cy.get("[data-cy=process-details]").find('button[title="More options"]').click();
+ cy.get("ul[data-cy=context-menu]").contains("Copy and re-run process").click();
});
- cy.get('[data-cy=form-dialog]').within(() => {
- cy.get('input[name=name]').clear().type(copiedCrName);
- cy.get('[data-cy=projects-tree-home-tree-picker]').click();
- cy.get('[data-cy=form-submit-btn]').click();
+ cy.get("[data-cy=form-dialog]").within(() => {
+ cy.get("input[name=name]").clear().type(copiedCrName);
+ cy.get("[data-cy=projects-tree-home-tree-picker]").click();
+ cy.get("[data-cy=form-submit-btn]").click();
});
- cy.get('[data-cy=process-details]').should('contain', copiedCrName);
- cy.get('[data-cy=process-details]').find('button').contains('Run');
+ cy.get("[data-cy=process-details]").should("contain", copiedCrName);
+ cy.get("[data-cy=process-details]").find("button").contains("Run");
});
- const getFakeContainer = (fakeContainerUuid) => ({
+ const getFakeContainer = fakeContainerUuid => ({
href: `/containers/${fakeContainerUuid}`,
kind: "arvados#container",
etag: "ecfosljpnxfari9a8m7e4yv06",
@@ -1184,12 +1159,12 @@ describe('Process tests', function() {
modified_by_user_uuid: "zzzzz-tpzed-000000000000000",
modified_at: "2023-02-15T19:12:45.987086000Z",
command: [
- "arvados-cwl-runner",
- "--api=containers",
- "--local",
- "--project-uuid=zzzzz-j7d0g-yr18k784zplfeza",
- "/var/lib/cwl/workflow.json#main",
- "/var/lib/cwl/cwl.input.json",
+ "arvados-cwl-runner",
+ "--api=containers",
+ "--local",
+ "--project-uuid=zzzzz-j7d0g-yr18k784zplfeza",
+ "/var/lib/cwl/workflow.json#main",
+ "/var/lib/cwl/cwl.input.json",
],
container_image: "4ad7d11381df349e464694762db14e04+303",
cwd: "/var/spool/cwl",
@@ -1202,24 +1177,24 @@ describe('Process tests', function() {
output_path: "/var/spool/cwl",
progress: null,
runtime_constraints: {
- API: true,
- cuda: {
- device_count: 0,
- driver_version: "",
- hardware_capability: "",
- },
- keep_cache_disk: 2147483648,
- keep_cache_ram: 0,
- ram: 1342177280,
- vcpus: 1,
+ API: true,
+ cuda: {
+ device_count: 0,
+ driver_version: "",
+ hardware_capability: "",
+ },
+ keep_cache_disk: 2147483648,
+ keep_cache_ram: 0,
+ ram: 1342177280,
+ vcpus: 1,
},
runtime_status: {},
started_at: null,
auth_uuid: null,
scheduling_parameters: {
- max_run_time: 0,
- partitions: [],
- preemptible: false,
+ max_run_time: 0,
+ partitions: [],
+ preemptible: false,
},
runtime_user_uuid: "zzzzz-tpzed-vllbpebicy84rd5",
runtime_auth_scopes: ["all"],
@@ -1230,45 +1205,38 @@ describe('Process tests', function() {
output_properties: {},
cost: 0.0,
subrequests_cost: 0.0,
- });
+ });
- it('shows cancel button when appropriate', function() {
+ it("shows cancel button when appropriate", function () {
// Ignore collection requests
- cy.intercept({method: 'GET', url: `**/arvados/v1/collections/*`}, {
- statusCode: 200,
- body: {}
- });
+ cy.intercept(
+ { method: "GET", url: `**/arvados/v1/collections/*` },
+ {
+ statusCode: 200,
+ body: {},
+ }
+ );
// Uncommitted container
const crUncommitted = `Test process ${Math.floor(Math.random() * 999999)}`;
- createContainerRequest(
- activeUser,
- crUncommitted,
- 'arvados/jobs',
- ['echo', 'hello world'],
- false, 'Uncommitted')
- .then(function(containerRequest) {
+ createContainerRequest(activeUser, crUncommitted, "arvados/jobs", ["echo", "hello world"], false, "Uncommitted").then(function (
+ containerRequest
+ ) {
// Navigate to process and verify run / cancel button
cy.goToPath(`/processes/${containerRequest.uuid}`);
cy.waitForDom();
- cy.get('[data-cy=process-details]').should('contain', crUncommitted);
- cy.get('[data-cy=process-run-button]').should('exist');
- cy.get('[data-cy=process-cancel-button]').should('not.exist');
+ cy.get("[data-cy=process-details]").should("contain", crUncommitted);
+ cy.get("[data-cy=process-run-button]").should("exist");
+ cy.get("[data-cy=process-cancel-button]").should("not.exist");
});
// Queued container
const crQueued = `Test process ${Math.floor(Math.random() * 999999)}`;
- const fakeCrUuid = 'zzzzz-dz642-000000000000001';
- createContainerRequest(
- activeUser,
- crQueued,
- 'arvados/jobs',
- ['echo', 'hello world'],
- false, 'Committed')
- .then(function(containerRequest) {
+ const fakeCrUuid = "zzzzz-dz642-000000000000001";
+ createContainerRequest(activeUser, crQueued, "arvados/jobs", ["echo", "hello world"], false, "Committed").then(function (containerRequest) {
// Fake container uuid
- cy.intercept({method: 'GET', url: `**/arvados/v1/container_requests/${containerRequest.uuid}`}, (req) => {
- req.reply((res) => {
+ cy.intercept({ method: "GET", url: `**/arvados/v1/container_requests/${containerRequest.uuid}` }, req => {
+ req.reply(res => {
res.body.output_uuid = fakeCrUuid;
res.body.priority = 500;
res.body.state = "Committed";
@@ -1277,31 +1245,28 @@ describe('Process tests', function() {
// Fake container
const container = getFakeContainer(fakeCrUuid);
- cy.intercept({method: 'GET', url: `**/arvados/v1/container/${fakeCrUuid}`}, {
- statusCode: 200,
- body: {...container, state: "Queued", priority: 500}
- });
+ cy.intercept(
+ { method: "GET", url: `**/arvados/v1/container/${fakeCrUuid}` },
+ {
+ statusCode: 200,
+ body: { ...container, state: "Queued", priority: 500 },
+ }
+ );
// Navigate to process and verify cancel button
cy.goToPath(`/processes/${containerRequest.uuid}`);
cy.waitForDom();
- cy.get('[data-cy=process-details]').should('contain', crQueued);
- cy.get('[data-cy=process-cancel-button]').contains('Cancel');
+ cy.get("[data-cy=process-details]").should("contain", crQueued);
+ cy.get("[data-cy=process-cancel-button]").contains("Cancel");
});
// Locked container
const crLocked = `Test process ${Math.floor(Math.random() * 999999)}`;
- const fakeCrLockedUuid = 'zzzzz-dz642-000000000000002';
- createContainerRequest(
- activeUser,
- crLocked,
- 'arvados/jobs',
- ['echo', 'hello world'],
- false, 'Committed')
- .then(function(containerRequest) {
+ const fakeCrLockedUuid = "zzzzz-dz642-000000000000002";
+ createContainerRequest(activeUser, crLocked, "arvados/jobs", ["echo", "hello world"], false, "Committed").then(function (containerRequest) {
// Fake container uuid
- cy.intercept({method: 'GET', url: `**/arvados/v1/container_requests/${containerRequest.uuid}`}, (req) => {
- req.reply((res) => {
+ cy.intercept({ method: "GET", url: `**/arvados/v1/container_requests/${containerRequest.uuid}` }, req => {
+ req.reply(res => {
res.body.output_uuid = fakeCrLockedUuid;
res.body.priority = 500;
res.body.state = "Committed";
@@ -1310,31 +1275,28 @@ describe('Process tests', function() {
// Fake container
const container = getFakeContainer(fakeCrLockedUuid);
- cy.intercept({method: 'GET', url: `**/arvados/v1/container/${fakeCrLockedUuid}`}, {
- statusCode: 200,
- body: {...container, state: "Locked", priority: 500}
- });
+ cy.intercept(
+ { method: "GET", url: `**/arvados/v1/container/${fakeCrLockedUuid}` },
+ {
+ statusCode: 200,
+ body: { ...container, state: "Locked", priority: 500 },
+ }
+ );
// Navigate to process and verify cancel button
cy.goToPath(`/processes/${containerRequest.uuid}`);
cy.waitForDom();
- cy.get('[data-cy=process-details]').should('contain', crLocked);
- cy.get('[data-cy=process-cancel-button]').contains('Cancel');
+ cy.get("[data-cy=process-details]").should("contain", crLocked);
+ cy.get("[data-cy=process-cancel-button]").contains("Cancel");
});
// On Hold container
const crOnHold = `Test process ${Math.floor(Math.random() * 999999)}`;
- const fakeCrOnHoldUuid = 'zzzzz-dz642-000000000000003';
- createContainerRequest(
- activeUser,
- crOnHold,
- 'arvados/jobs',
- ['echo', 'hello world'],
- false, 'Committed')
- .then(function(containerRequest) {
+ const fakeCrOnHoldUuid = "zzzzz-dz642-000000000000003";
+ createContainerRequest(activeUser, crOnHold, "arvados/jobs", ["echo", "hello world"], false, "Committed").then(function (containerRequest) {
// Fake container uuid
- cy.intercept({method: 'GET', url: `**/arvados/v1/container_requests/${containerRequest.uuid}`}, (req) => {
- req.reply((res) => {
+ cy.intercept({ method: "GET", url: `**/arvados/v1/container_requests/${containerRequest.uuid}` }, req => {
+ req.reply(res => {
res.body.output_uuid = fakeCrOnHoldUuid;
res.body.priority = 0;
res.body.state = "Committed";
@@ -1343,18 +1305,20 @@ describe('Process tests', function() {
// Fake container
const container = getFakeContainer(fakeCrOnHoldUuid);
- cy.intercept({method: 'GET', url: `**/arvados/v1/container/${fakeCrOnHoldUuid}`}, {
- statusCode: 200,
- body: {...container, state: "Queued", priority: 0}
- });
+ cy.intercept(
+ { method: "GET", url: `**/arvados/v1/container/${fakeCrOnHoldUuid}` },
+ {
+ statusCode: 200,
+ body: { ...container, state: "Queued", priority: 0 },
+ }
+ );
// Navigate to process and verify cancel button
cy.goToPath(`/processes/${containerRequest.uuid}`);
cy.waitForDom();
- cy.get('[data-cy=process-details]').should('contain', crOnHold);
- cy.get('[data-cy=process-run-button]').should('exist');
- cy.get('[data-cy=process-cancel-button]').should('not.exist');
+ cy.get("[data-cy=process-details]").should("contain", crOnHold);
+ cy.get("[data-cy=process-run-button]").should("exist");
+ cy.get("[data-cy=process-cancel-button]").should("not.exist");
});
});
-
});
diff --git a/src/components/data-explorer/data-explorer.test.tsx b/src/components/data-explorer/data-explorer.test.tsx
index ffb21417..b86567a5 100644
--- a/src/components/data-explorer/data-explorer.test.tsx
+++ b/src/components/data-explorer/data-explorer.test.tsx
@@ -56,74 +56,80 @@ describe("<DataExplorer />", () => {
expect(onSearch).toHaveBeenCalledWith("new value");
});
- // it("communicates with <ColumnSelector/>", () => {
- // const onColumnToggle = jest.fn();
- // const onSetColumns = jest.fn();
- // const columns = [{ name: "Column 1", render: jest.fn(), selected: true, configurable: true, sortDirection: SortDirection.ASC, filters: {} }];
- // const dataExplorer = mount(
- // <DataExplorer
- // {...mockDataExplorerProps()}
- // columns={columns}
- // onColumnToggle={onColumnToggle}
- // items={[{ name: "item 1" }]}
- // onSetColumns={onSetColumns}
- // />
- // );
- // expect(dataExplorer.find(ColumnSelector).prop("columns")).toBe(columns);
- // dataExplorer.find(ColumnSelector).prop("onColumnToggle")("columns");
- // expect(onColumnToggle).toHaveBeenCalledWith("columns");
- // });
+ it("communicates with <ColumnSelector/>", () => {
+ const onColumnToggle = jest.fn();
+ const onSetColumns = jest.fn();
+ const columns = [{ name: "Column 1", render: jest.fn(), selected: true, configurable: true, sortDirection: SortDirection.ASC, filters: {} }];
+ const dataExplorer = mount(
+ <Provider store={store}>
+ <DataExplorer
+ {...mockDataExplorerProps()}
+ columns={columns}
+ onColumnToggle={onColumnToggle}
+ items={[{ name: "item 1" }]}
+ onSetColumns={onSetColumns}
+ />
+ </Provider>
+ );
+ expect(dataExplorer.find(ColumnSelector).prop("columns")).toBe(columns);
+ dataExplorer.find(ColumnSelector).prop("onColumnToggle")("columns");
+ expect(onColumnToggle).toHaveBeenCalledWith("columns");
+ });
- // it("communicates with <DataTable/>", () => {
- // const onFiltersChange = jest.fn();
- // const onSortToggle = jest.fn();
- // const onRowClick = jest.fn();
- // const onSetColumns = jest.fn();
- // const columns = [{ name: "Column 1", render: jest.fn(), selected: true, configurable: true, sortDirection: SortDirection.ASC, filters: {} }];
- // const items = [{ name: "item 1" }];
- // const dataExplorer = mount(
- // <DataExplorer
- // {...mockDataExplorerProps()}
- // columns={columns}
- // items={items}
- // onFiltersChange={onFiltersChange}
- // onSortToggle={onSortToggle}
- // onRowClick={onRowClick}
- // onSetColumns={onSetColumns}
- // />
- // );
- // expect(dataExplorer.find(DataTable).prop("columns").slice(1, 2)).toEqual(columns);
- // expect(dataExplorer.find(DataTable).prop("items")).toBe(items);
- // dataExplorer.find(DataTable).prop("onRowClick")("event", "rowClick");
- // dataExplorer.find(DataTable).prop("onFiltersChange")("filtersChange");
- // dataExplorer.find(DataTable).prop("onSortToggle")("sortToggle");
- // expect(onFiltersChange).toHaveBeenCalledWith("filtersChange");
- // expect(onSortToggle).toHaveBeenCalledWith("sortToggle");
- // expect(onRowClick).toHaveBeenCalledWith("rowClick");
- // });
+ it("communicates with <DataTable/>", () => {
+ const onFiltersChange = jest.fn();
+ const onSortToggle = jest.fn();
+ const onRowClick = jest.fn();
+ const onSetColumns = jest.fn();
+ const columns = [{ name: "Column 1", render: jest.fn(), selected: true, configurable: true, sortDirection: SortDirection.ASC, filters: {} }];
+ const items = [{ name: "item 1" }];
+ const dataExplorer = mount(
+ <Provider store={store}>
+ <DataExplorer
+ {...mockDataExplorerProps()}
+ columns={columns}
+ items={items}
+ onFiltersChange={onFiltersChange}
+ onSortToggle={onSortToggle}
+ onRowClick={onRowClick}
+ onSetColumns={onSetColumns}
+ />
+ </Provider>
+ );
+ expect(dataExplorer.find(DataTable).prop("columns").slice(1, 2)).toEqual(columns);
+ expect(dataExplorer.find(DataTable).prop("items")).toBe(items);
+ dataExplorer.find(DataTable).prop("onRowClick")("event", "rowClick");
+ dataExplorer.find(DataTable).prop("onFiltersChange")("filtersChange");
+ dataExplorer.find(DataTable).prop("onSortToggle")("sortToggle");
+ expect(onFiltersChange).toHaveBeenCalledWith("filtersChange");
+ expect(onSortToggle).toHaveBeenCalledWith("sortToggle");
+ expect(onRowClick).toHaveBeenCalledWith("rowClick");
+ });
- // it("communicates with <TablePagination/>", () => {
- // const onChangePage = jest.fn();
- // const onChangeRowsPerPage = jest.fn();
- // const onSetColumns = jest.fn();
- // const dataExplorer = mount(
- // <DataExplorer
- // {...mockDataExplorerProps()}
- // items={[{ name: "item 1" }]}
- // page={10}
- // rowsPerPage={50}
- // onChangePage={onChangePage}
- // onChangeRowsPerPage={onChangeRowsPerPage}
- // onSetColumns={onSetColumns}
- // />
- // );
- // expect(dataExplorer.find(TablePagination).prop("page")).toEqual(10);
- // expect(dataExplorer.find(TablePagination).prop("rowsPerPage")).toEqual(50);
- // dataExplorer.find(TablePagination).prop("onChangePage")(undefined, 6);
- // dataExplorer.find(TablePagination).prop("onChangeRowsPerPage")({ target: { value: 10 } });
- // expect(onChangePage).toHaveBeenCalledWith(6);
- // expect(onChangeRowsPerPage).toHaveBeenCalledWith(10);
- // });
+ it("communicates with <TablePagination/>", () => {
+ const onChangePage = jest.fn();
+ const onChangeRowsPerPage = jest.fn();
+ const onSetColumns = jest.fn();
+ const dataExplorer = mount(
+ <Provider store={store}>
+ <DataExplorer
+ {...mockDataExplorerProps()}
+ items={[{ name: "item 1" }]}
+ page={10}
+ rowsPerPage={50}
+ onChangePage={onChangePage}
+ onChangeRowsPerPage={onChangeRowsPerPage}
+ onSetColumns={onSetColumns}
+ />
+ </Provider>
+ );
+ expect(dataExplorer.find(TablePagination).prop("page")).toEqual(10);
+ expect(dataExplorer.find(TablePagination).prop("rowsPerPage")).toEqual(50);
+ dataExplorer.find(TablePagination).prop("onChangePage")(undefined, 6);
+ dataExplorer.find(TablePagination).prop("onChangeRowsPerPage")({ target: { value: 10 } });
+ expect(onChangePage).toHaveBeenCalledWith(6);
+ expect(onChangeRowsPerPage).toHaveBeenCalledWith(10);
+ });
});
const mockDataExplorerProps = () => ({
diff --git a/src/services/collection-service/collection-service.ts b/src/services/collection-service/collection-service.ts
index 74cf7595..4bd989e0 100644
--- a/src/services/collection-service/collection-service.ts
+++ b/src/services/collection-service/collection-service.ts
@@ -15,19 +15,19 @@ import { CommonService } from "services/common-service/common-service";
export type UploadProgress = (fileId: number, loaded: number, total: number, currentTime: number) => void;
-export const emptyCollectionPdh = 'd41d8cd98f00b204e9800998ecf8427e+0';
+export const emptyCollectionPdh = "d41d8cd98f00b204e9800998ecf8427e+0";
export class CollectionService extends TrashableResourceService<CollectionResource> {
constructor(serverApi: AxiosInstance, private webdavClient: WebDAV, private authService: AuthService, actions: ApiActions) {
super(serverApi, "collections", actions, [
- 'fileCount',
- 'fileSizeTotal',
- 'replicationConfirmed',
- 'replicationConfirmedAt',
- 'storageClassesConfirmed',
- 'storageClassesConfirmedAt',
- 'unsignedManifestText',
- 'version',
+ "fileCount",
+ "fileSizeTotal",
+ "replicationConfirmed",
+ "replicationConfirmedAt",
+ "storageClassesConfirmed",
+ "storageClassesConfirmedAt",
+ "unsignedManifestText",
+ "version",
]);
}
@@ -42,7 +42,7 @@ export class CollectionService extends TrashableResourceService<CollectionResour
}
update(uuid: string, data: Partial<CollectionResource>, showErrors?: boolean) {
- const select = [...Object.keys(data), 'version', 'modifiedAt'];
+ const select = [...Object.keys(data), "version", "modifiedAt"];
return super.update(uuid, { ...data, preserveVersion: true }, showErrors, select);
}
@@ -51,15 +51,16 @@ export class CollectionService extends TrashableResourceService<CollectionResour
if (request.responseXML != null) {
return extractFilesData(request.responseXML);
}
+
return Promise.reject();
}
private combineFilePath(parts: string[]) {
return parts.reduce((path, part) => {
// Trim leading and trailing slashes
- const trimmedPart = part.split('/').filter(Boolean).join('/');
+ const trimmedPart = part.split("/").filter(Boolean).join("/");
if (trimmedPart.length) {
- const separator = path.endsWith('/') ? '' : '/';
+ const separator = path.endsWith("/") ? "" : "/";
return `${path}${separator}${trimmedPart}`;
} else {
return path;
@@ -70,22 +71,23 @@ export class CollectionService extends TrashableResourceService<CollectionResour
private replaceFiles(collectionUuid: string, fileMap: {}, showErrors?: boolean) {
const payload = {
collection: {
- preserve_version: true
+ preserve_version: true,
},
- replace_files: fileMap
+ replace_files: fileMap,
};
return CommonService.defaultResponse(
- this.serverApi
- .put<CollectionResource>(`/${this.resourceType}/${collectionUuid}`, payload),
+ this.serverApi.put<CollectionResource>(`/${this.resourceType}/${collectionUuid}`, payload),
this.actions,
true, // mapKeys
showErrors
);
}
- async uploadFiles(collectionUuid: string, files: File[], onProgress?: UploadProgress, targetLocation: string = '') {
- if (collectionUuid === "" || files.length === 0) { return; }
+ async uploadFiles(collectionUuid: string, files: File[], onProgress?: UploadProgress, targetLocation: string = "") {
+ if (collectionUuid === "" || files.length === 0) {
+ return;
+ }
// files have to be uploaded sequentially
for (let idx = 0; idx < files.length; idx++) {
await this.uploadFile(collectionUuid, files[idx], idx, onProgress, targetLocation);
@@ -96,34 +98,40 @@ export class CollectionService extends TrashableResourceService<CollectionResour
async renameFile(collectionUuid: string, collectionPdh: string, oldPath: string, newPath: string) {
return this.replaceFiles(collectionUuid, {
[this.combineFilePath([newPath])]: `${collectionPdh}${this.combineFilePath([oldPath])}`,
- [this.combineFilePath([oldPath])]: '',
+ [this.combineFilePath([oldPath])]: "",
});
}
extendFileURL = (file: CollectionDirectory | CollectionFile) => {
- const baseUrl = this.webdavClient.getBaseUrl().endsWith('/')
- ? this.webdavClient.getBaseUrl().slice(0, -1)
- : this.webdavClient.getBaseUrl();
+ const baseUrl = this.webdavClient.getBaseUrl().endsWith("/") ? this.webdavClient.getBaseUrl().slice(0, -1) : this.webdavClient.getBaseUrl();
const apiToken = this.authService.getApiToken();
- const encodedApiToken = apiToken ? encodeURI(apiToken) : '';
+ const encodedApiToken = apiToken ? encodeURI(apiToken) : "";
const userApiToken = `/t=${encodedApiToken}/`;
- const splittedPrevFileUrl = file.url.split('/');
- const url = `${baseUrl}/${splittedPrevFileUrl[1]}${userApiToken}${splittedPrevFileUrl.slice(2).join('/')}`;
+ const splittedPrevFileUrl = file.url.split("/");
+ const url = `${baseUrl}/${splittedPrevFileUrl[1]}${userApiToken}${splittedPrevFileUrl.slice(2).join("/")}`;
return {
...file,
- url
+ url,
};
- }
+ };
async getFileContents(file: CollectionFile) {
return (await this.webdavClient.get(`c=${file.id}`)).response;
}
- private async uploadFile(collectionUuid: string, file: File, fileId: number, onProgress: UploadProgress = () => { return; }, targetLocation: string = '') {
- const fileURL = `c=${targetLocation !== '' ? targetLocation : collectionUuid}/${file.name}`.replace('//', '/');
+ private async uploadFile(
+ collectionUuid: string,
+ file: File,
+ fileId: number,
+ onProgress: UploadProgress = () => {
+ return;
+ },
+ targetLocation: string = ""
+ ) {
+ const fileURL = `c=${targetLocation !== "" ? targetLocation : collectionUuid}/${file.name}`.replace("//", "/");
const requestConfig = {
headers: {
- 'Content-Type': 'text/octet-stream'
+ "Content-Type": "text/octet-stream",
},
onUploadProgress: (e: ProgressEvent) => {
onProgress(fileId, e.loaded, e.total, Date.now());
@@ -136,7 +144,7 @@ export class CollectionService extends TrashableResourceService<CollectionResour
const optimizedFiles = files
.sort((a, b) => a.length - b.length)
.reduce((acc, currentPath) => {
- const parentPathFound = acc.find((parentPath) => currentPath.indexOf(`${parentPath}/`) > -1);
+ const parentPathFound = acc.find(parentPath => currentPath.indexOf(`${parentPath}/`) > -1);
if (!parentPathFound) {
return [...acc, currentPath];
@@ -148,49 +156,54 @@ export class CollectionService extends TrashableResourceService<CollectionResour
const fileMap = optimizedFiles.reduce((obj, filePath) => {
return {
...obj,
- [this.combineFilePath([filePath])]: ''
- }
- }, {})
+ [this.combineFilePath([filePath])]: "",
+ };
+ }, {});
return this.replaceFiles(collectionUuid, fileMap, showErrors);
}
copyFiles(sourcePdh: string, files: string[], destinationCollectionUuid: string, destinationPath: string, showErrors?: boolean) {
const fileMap = files.reduce((obj, sourceFile) => {
- const sourceFileName = sourceFile.split('/').filter(Boolean).slice(-1).join("");
+ const sourceFileName = sourceFile.split("/").filter(Boolean).slice(-1).join("");
return {
...obj,
- [this.combineFilePath([destinationPath, sourceFileName])]: `${sourcePdh}${this.combineFilePath([sourceFile])}`
+ [this.combineFilePath([destinationPath, sourceFileName])]: `${sourcePdh}${this.combineFilePath([sourceFile])}`,
};
}, {});
return this.replaceFiles(destinationCollectionUuid, fileMap, showErrors);
}
- moveFiles(sourceUuid: string, sourcePdh: string, files: string[], destinationCollectionUuid: string, destinationPath: string, showErrors?: boolean) {
+ moveFiles(
+ sourceUuid: string,
+ sourcePdh: string,
+ files: string[],
+ destinationCollectionUuid: string,
+ destinationPath: string,
+ showErrors?: boolean
+ ) {
if (sourceUuid === destinationCollectionUuid) {
const fileMap = files.reduce((obj, sourceFile) => {
- const sourceFileName = sourceFile.split('/').filter(Boolean).slice(-1).join("");
+ const sourceFileName = sourceFile.split("/").filter(Boolean).slice(-1).join("");
return {
...obj,
[this.combineFilePath([destinationPath, sourceFileName])]: `${sourcePdh}${this.combineFilePath([sourceFile])}`,
- [this.combineFilePath([sourceFile])]: '',
+ [this.combineFilePath([sourceFile])]: "",
};
}, {});
- return this.replaceFiles(sourceUuid, fileMap, showErrors)
+ return this.replaceFiles(sourceUuid, fileMap, showErrors);
} else {
- return this.copyFiles(sourcePdh, files, destinationCollectionUuid, destinationPath, showErrors)
- .then(() => {
- return this.deleteFiles(sourceUuid, files, showErrors);
- });
+ return this.copyFiles(sourcePdh, files, destinationCollectionUuid, destinationPath, showErrors).then(() => {
+ return this.deleteFiles(sourceUuid, files, showErrors);
+ });
}
}
createDirectory(collectionUuid: string, path: string, showErrors?: boolean) {
- const fileMap = {[this.combineFilePath([path])]: emptyCollectionPdh};
+ const fileMap = { [this.combineFilePath([path])]: emptyCollectionPdh };
return this.replaceFiles(collectionUuid, fileMap, showErrors);
}
-
}
diff --git a/src/views-components/context-menu/action-sets/process-resource-action-set.ts b/src/views-components/context-menu/action-sets/process-resource-action-set.ts
index aceebe06..7d039b13 100644
--- a/src/views-components/context-menu/action-sets/process-resource-action-set.ts
+++ b/src/views-components/context-menu/action-sets/process-resource-action-set.ts
@@ -35,36 +35,32 @@ export const readOnlyProcessResourceActionSet: ContextMenuActionSet = [
{
component: ToggleFavoriteAction,
execute: (dispatch, resources) => {
- resources.forEach(resource =>
- dispatch<any>(toggleFavorite(resource)).then(() => {
- dispatch<any>(favoritePanelActions.REQUEST_ITEMS());
- })
- );
+ dispatch<any>(toggleFavorite(resources[0])).then(() => {
+ dispatch<any>(favoritePanelActions.REQUEST_ITEMS());
+ });
},
},
{
icon: OpenIcon,
name: "Open in new tab",
execute: (dispatch, resources) => {
- resources.forEach(resource => dispatch<any>(openInNewTabAction(resource)));
+ dispatch<any>(openInNewTabAction(resources[0]));
},
},
{
icon: ReRunProcessIcon,
name: "Copy and re-run process",
execute: (dispatch, resources) => {
- resources.forEach(resource => dispatch<any>(openCopyProcessDialog(resource)));
+ dispatch<any>(openCopyProcessDialog(resources[0]));
},
},
{
icon: OutputIcon,
name: "Outputs",
execute: (dispatch, resources) => {
- resources.forEach(resource => {
- if (resource.outputUuid) {
- dispatch<any>(navigateToOutput(resource.outputUuid));
- }
- });
+ if (resources[0].outputUuid) {
+ dispatch<any>(navigateToOutput(resources[0].outputUuid));
+ }
},
},
{
@@ -78,7 +74,7 @@ export const readOnlyProcessResourceActionSet: ContextMenuActionSet = [
icon: AdvancedIcon,
name: "API Details",
execute: (dispatch, resources) => {
- resources.forEach(resource => dispatch<any>(openAdvancedTabDialog(resource.uuid)));
+ dispatch<any>(openAdvancedTabDialog(resources[0].uuid));
},
},
],
@@ -91,14 +87,14 @@ export const processResourceActionSet: ContextMenuActionSet = [
icon: RenameIcon,
name: "Edit process",
execute: (dispatch, resources) => {
- resources.forEach(resource => dispatch<any>(openProcessUpdateDialog(resource)));
+ dispatch<any>(openProcessUpdateDialog(resources[0]));
},
},
{
icon: ShareIcon,
name: "Share",
execute: (dispatch, resources) => {
- resources.forEach(({ uuid }) => dispatch<any>(openSharingDialog(uuid)));
+ dispatch<any>(openSharingDialog(resources[0].uuid));
},
},
{
@@ -125,11 +121,9 @@ export const processResourceAdminActionSet: ContextMenuActionSet = [
component: TogglePublicFavoriteAction,
name: "Add to public favorites",
execute: (dispatch, resources) => {
- resources.forEach(resource =>
- dispatch<any>(togglePublicFavorite(resource)).then(() => {
- dispatch<any>(publicFavoritePanelActions.REQUEST_ITEMS());
- })
- );
+ dispatch<any>(togglePublicFavorite(resources[0])).then(() => {
+ dispatch<any>(publicFavoritePanelActions.REQUEST_ITEMS());
+ });
},
},
],
diff --git a/src/views-components/multiselect-toolbar/ms-collection-action-set.ts b/src/views-components/multiselect-toolbar/ms-collection-action-set.ts
index 77215470..2ea1a99a 100644
--- a/src/views-components/multiselect-toolbar/ms-collection-action-set.ts
+++ b/src/views-components/multiselect-toolbar/ms-collection-action-set.ts
@@ -16,7 +16,6 @@ export const msCollectionActionSet: ContextMenuActionSet = [
icon: CopyIcon,
name: "Make a copy",
execute: (dispatch, [...resources]) => {
- console.log(resources);
if (resources[0].isSingle || resources.length === 1) dispatch<any>(openCollectionCopyDialog(resources[0]));
else dispatch<any>(openMultiCollectionCopyDialog(resources[0]));
},
diff --git a/src/views-components/multiselect-toolbar/ms-process-action-set.ts b/src/views-components/multiselect-toolbar/ms-process-action-set.ts
index cf629993..820fc799 100644
--- a/src/views-components/multiselect-toolbar/ms-process-action-set.ts
+++ b/src/views-components/multiselect-toolbar/ms-process-action-set.ts
@@ -14,7 +14,9 @@ export const msProcessActionSet: ContextMenuActionSet = [
icon: ReRunProcessIcon,
name: "Copy and re-run process",
execute: (dispatch, resources) => {
- resources.forEach(resource => dispatch<any>(openCopyProcessDialog(resource)));
+ for (const resource of [...resources]) {
+ dispatch<any>(openCopyProcessDialog(resource));
+ }
},
},
{
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list