Skip to content

Commit

Permalink
DEVPROD-9562: Create distros table on Build Information page (#302)
Browse files Browse the repository at this point in the history
  • Loading branch information
minnakt authored Aug 14, 2024
1 parent 3f769db commit 3b60a0d
Show file tree
Hide file tree
Showing 22 changed files with 630 additions and 49 deletions.
9 changes: 9 additions & 0 deletions apps/spruce/cypress/integration/image/build_information.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
describe("build information", () => {
describe("distros", () => {
it("should show the corresponding distros", () => {
cy.visit("/image/ubuntu1804");
cy.dataCy("distro-table-row").should("have.length", 1);
cy.contains("ubuntu1804-workstation");
});
});
});
12 changes: 6 additions & 6 deletions apps/spruce/cypress/integration/preferences/notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,18 @@ describe("user subscriptions table", () => {
});

it("shows all of a user's subscriptions and expands with details", () => {
cy.dataCy("leafygreen-table-row").should("have.length", 3);
cy.dataCy("subscription-row").should("have.length", 3);

cy.dataCy("regex-selectors").should("not.be.visible");
cy.dataCy("trigger-data").should("not.be.visible");
cy.dataCy("leafygreen-table-row")
cy.dataCy("subscription-row")
.eq(0)
.within(() => {
cy.get("button").first().click();
});
cy.dataCy("regex-selectors").should("be.visible");
cy.dataCy("trigger-data").should("not.be.visible");
cy.dataCy("leafygreen-table-row")
cy.dataCy("subscription-row")
.eq(2)
.within(() => {
cy.get("button").first().click();
Expand All @@ -52,7 +52,7 @@ describe("user subscriptions table", () => {
});

it("Shows the selected count in the 'Delete' button", () => {
cy.dataCy("leafygreen-table-row")
cy.dataCy("subscription-row")
.eq(0)
.within(() => {
cy.get("input[type=checkbox]").check({ force: true });
Expand All @@ -77,14 +77,14 @@ describe("user subscriptions table", () => {

describe("Deleting subscriptions", () => {
it("Deletes a single subscription", () => {
cy.dataCy("leafygreen-table-row")
cy.dataCy("subscription-row")
.eq(0)
.within(() => {
cy.get("input[type=checkbox]").check({ force: true });
});
cy.dataCy("delete-some-button").click();
cy.validateToast("success", "Deleted 1 subscription.");
cy.dataCy("leafygreen-table-row").should("have.length", 2);
cy.dataCy("subscription-row").should("have.length", 2);
});
});
});
14 changes: 9 additions & 5 deletions apps/spruce/cypress/integration/version/task_duration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe("Task Duration Tab", () => {
cy.dataCy("task-name-filter-popover-input-filter").type(
`${filterText}{enter}`,
);
cy.dataCy("leafygreen-table-row").should("have.length", 1);
cy.dataCy("task-duration-table-row").should("have.length", 1);
cy.location("search").should(
"include",
`duration=DESC&page=0&taskName=${filterText}`,
Expand All @@ -28,7 +28,7 @@ describe("Task Duration Tab", () => {
cy.dataCy("tree-select-options").within(() =>
cy.contains("Running").click({ force: true }),
);
cy.dataCy("leafygreen-table-row").should("have.length", 3);
cy.dataCy("task-duration-table-row").should("have.length", 3);
cy.location("search").should(
"include",
"duration=DESC&page=0&statuses=running-umbrella%2Cstarted%2Cdispatched",
Expand All @@ -48,7 +48,7 @@ describe("Task Duration Tab", () => {
cy.dataCy("build-variant-filter-popover-input-filter").type(
`${filterText}{enter}`,
);
cy.dataCy("leafygreen-table-row").should("have.length", 2);
cy.dataCy("task-duration-table-row").should("have.length", 2);
cy.location("search").should(
"include",
`duration=DESC&page=0&variant=${filterText}`,
Expand All @@ -66,14 +66,18 @@ describe("Task Duration Tab", () => {
cy.location("search").should("include", "duration=DESC");
const longestTask = "test-thirdparty";
cy.contains(longestTask).should("be.visible");
cy.dataCy("leafygreen-table-row").first().should("contain", longestTask);
cy.dataCy("task-duration-table-row")
.first()
.should("contain", longestTask);
cy.get(durationSortControl).click();
cy.location("search").should("not.include", "duration");
cy.get(durationSortControl).click();
cy.location("search").should("include", "duration=ASC");
const shortestTask = "test-auth";
cy.contains(shortestTask).should("be.visible");
cy.dataCy("leafygreen-table-row").first().should("contain", shortestTask);
cy.dataCy("task-duration-table-row")
.first()
.should("contain", shortestTask);
});

it("clearing all filters resets to the default sort", () => {
Expand Down
6 changes: 5 additions & 1 deletion apps/spruce/src/components/Table/BaseTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ export const BaseTable = forwardRef(
key={row.id}
virtualRow={vr}
isSelected={selectedRowIndexes.includes(row.index)}
dataCyRow={dataCyRow}
/>
);
})
Expand All @@ -166,6 +167,7 @@ export const BaseTable = forwardRef(
// @ts-expect-error: FIXME. This comment was added by an automated script.
virtualRow={null}
isSelected={selectedRowIndexes.includes(row.index)}
dataCyRow={dataCyRow}
/>
))}
</TableBody>
Expand All @@ -183,17 +185,19 @@ export const BaseTable = forwardRef(
const cellPaddingStyle = { paddingBottom: size.xxs, paddingTop: size.xxs };

const RenderableRow = <T extends LGRowData>({
dataCyRow = "leafygreen-table-row",
isSelected = false,
row,
virtualRow,
}: {
dataCyRow?: string;
row: LeafyGreenTableRow<T>;
virtualRow: VirtualItem;
isSelected?: boolean;
}) => (
<Row
row={row}
data-cy="leafygreen-table-row"
data-cy={dataCyRow}
className={css`
&[aria-hidden="false"] td > div {
max-height: unset;
Expand Down
3 changes: 3 additions & 0 deletions apps/spruce/src/constants/externalResources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ export const wikiUrl = `${wikiBaseUrl}/Home`;
const projectSettingsDocumentationUrl = `${wikiBaseUrl}/Project-Configuration`;
const hostsDocumentationUrl = `${wikiBaseUrl}/Hosts`;

export const amazonEC2InstanceTypeDocumentationUrl =
"https://aws.amazon.com/ec2/instance-types/";

export const hostUptimeDocumentationUrl = `${hostsDocumentationUrl}/Spawn-Hosts#unexpirable-host-sleep-schedules`;

export const projectDistroSettingsDocumentationUrl = `${projectSettingsDocumentationUrl}/Project-and-Distro-Settings`;
Expand Down
2 changes: 2 additions & 0 deletions apps/spruce/src/constants/hosts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ export const hostStatuses: Status[] = [
];

export const MCI_USER = "mci";

export const defaultEC2Region = "us-east-1";
22 changes: 22 additions & 0 deletions apps/spruce/src/gql/generated/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6272,6 +6272,28 @@ export type HostsQuery = {
};
};

export type ImageDistrosQueryVariables = Exact<{
imageId: Scalars["String"]["input"];
}>;

export type ImageDistrosQuery = {
__typename?: "Query";
image?: {
__typename?: "Image";
id: string;
distros: Array<{
__typename?: "Distro";
name: string;
provider: Provider;
providerSettingsList: Array<any>;
hostAllocatorSettings: {
__typename?: "HostAllocatorSettings";
maximumHosts: number;
};
}>;
} | null;
};

export type ImagesQueryVariables = Exact<{ [key: string]: never }>;

export type ImagesQuery = { __typename?: "Query"; images: Array<string> };
Expand Down
13 changes: 13 additions & 0 deletions apps/spruce/src/gql/queries/image-distros.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
query ImageDistros($imageId: String!) {
image(imageId: $imageId) {
distros {
hostAllocatorSettings {
maximumHosts
}
name
provider
providerSettingsList
}
id
}
}
2 changes: 2 additions & 0 deletions apps/spruce/src/gql/queries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import HAS_VERSION from "./has-version.graphql";
import HOST_EVENTS from "./host-events.graphql";
import HOST from "./host.graphql";
import HOSTS from "./hosts.graphql";
import IMAGE_DISTROS from "./image-distros.graphql";
import IMAGES from "./images.graphql";
import INSTANCE_TYPES from "./instance-types.graphql";
import IS_PATCH_CONFIGURED from "./is-patch-configured.graphql";
Expand Down Expand Up @@ -110,6 +111,7 @@ export {
HOST_EVENTS,
HOST,
HOSTS,
IMAGE_DISTROS,
IMAGES,
INSTANCE_TYPES,
IS_PATCH_CONFIGURED,
Expand Down
172 changes: 172 additions & 0 deletions apps/spruce/src/pages/image/DistrosTable/DistrosTable.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import { MockedProvider } from "@apollo/client/testing";
import { RenderFakeToastContext } from "context/toast/__mocks__";
import {
ImageDistrosQuery,
ImageDistrosQueryVariables,
Provider,
} from "gql/generated/types";
import { IMAGE_DISTROS } from "gql/queries";
import {
renderWithRouterMatch as render,
screen,
waitFor,
within,
} from "test_utils";
import { ApolloMock } from "types/gql";
import { DistrosTable } from ".";

const wrapper = ({ children }: { children: React.ReactNode }) => (
<MockedProvider mocks={[imageDistrosMock]}>{children}</MockedProvider>
);

describe("distros table", () => {
it("shows correct links to distro pages", async () => {
const { Component } = RenderFakeToastContext(
<DistrosTable imageId="ubuntu2204" />,
);
render(<Component />, { wrapper });
await waitFor(() => {
expect(screen.getAllByDataCy("distro-table-row")).toHaveLength(3);
});

const ubuntuSmall = screen.getAllByDataCy("distro-table-row")[0];
expect(within(ubuntuSmall).getAllByRole("link")[0]).toHaveAttribute(
"href",
"/distro/ubuntu2204-small/settings/general",
);
const ubuntuLarge = screen.getAllByDataCy("distro-table-row")[1];
expect(within(ubuntuLarge).getAllByRole("link")[0]).toHaveAttribute(
"href",
"/distro/ubuntu2204-large/settings/general",
);
const ubuntuStatic = screen.getAllByDataCy("distro-table-row")[2];
expect(within(ubuntuStatic).getAllByRole("link")[0]).toHaveAttribute(
"href",
"/distro/ubuntu2204-static/settings/general",
);
});

it("shows correct instance types", async () => {
const { Component } = RenderFakeToastContext(
<DistrosTable imageId="ubuntu2204" />,
);
render(<Component />, { wrapper });
await waitFor(() => {
expect(screen.getAllByDataCy("distro-table-row")).toHaveLength(3);
});

const ubuntuSmall = screen.getAllByDataCy("distro-table-row")[0];
expect(within(ubuntuSmall).getAllByRole("cell")[1]).toHaveTextContent(
"m4.xlarge",
);
const ubuntuLarge = screen.getAllByDataCy("distro-table-row")[1];
expect(within(ubuntuLarge).getAllByRole("cell")[1]).toHaveTextContent(
"m6i.2xlarge",
);
const ubuntuStatic = screen.getAllByDataCy("distro-table-row")[2];
expect(within(ubuntuStatic).getAllByRole("cell")[1]).toHaveTextContent(
"N/A",
);
});

it("shows correct max host counts", async () => {
const { Component } = RenderFakeToastContext(
<DistrosTable imageId="ubuntu2204" />,
);
render(<Component />, { wrapper });
await waitFor(() => {
expect(screen.getAllByDataCy("distro-table-row")).toHaveLength(3);
});

const ubuntuSmall = screen.getAllByDataCy("distro-table-row")[0];
expect(within(ubuntuSmall).getAllByRole("cell")[2]).toHaveTextContent(
"100",
);
const ubuntuLarge = screen.getAllByDataCy("distro-table-row")[1];
expect(within(ubuntuLarge).getAllByRole("cell")[2]).toHaveTextContent("30");
const ubuntuStatic = screen.getAllByDataCy("distro-table-row")[2];
expect(within(ubuntuStatic).getAllByRole("cell")[2]).toHaveTextContent("2");
});

it("shows correct links to hosts pages", async () => {
const { Component } = RenderFakeToastContext(
<DistrosTable imageId="ubuntu2204" />,
);
render(<Component />, { wrapper });
await waitFor(() => {
expect(screen.getAllByDataCy("distro-table-row")).toHaveLength(3);
});

const ubuntuSmall = screen.getAllByDataCy("distro-table-row")[0];
expect(within(ubuntuSmall).getAllByRole("link")[1]).toHaveAttribute(
"href",
"/hosts?distroId=ubuntu2204-small&startedBy=mci",
);
const ubuntuLarge = screen.getAllByDataCy("distro-table-row")[1];
expect(within(ubuntuLarge).getAllByRole("link")[1]).toHaveAttribute(
"href",
"/hosts?distroId=ubuntu2204-large&startedBy=mci",
);
const ubuntuStatic = screen.getAllByDataCy("distro-table-row")[2];
expect(within(ubuntuStatic).getAllByRole("link")[1]).toHaveAttribute(
"href",
"/hosts?distroId=ubuntu2204-static&startedBy=mci",
);
});
});

const imageDistrosMock: ApolloMock<
ImageDistrosQuery,
ImageDistrosQueryVariables
> = {
request: {
query: IMAGE_DISTROS,
variables: { imageId: "ubuntu2204" },
},
result: {
data: {
image: {
__typename: "Image",
id: "ubuntu2204",
distros: [
{
__typename: "Distro",
name: "ubuntu2204-small",
provider: Provider.Ec2Fleet,
providerSettingsList: [
{ region: "us-east-1", instance_type: "m4.xlarge" },
{ region: "us-west-1", instance_type: "m4.4xlarge" },
],
hostAllocatorSettings: {
__typename: "HostAllocatorSettings",
maximumHosts: 100,
},
},
{
__typename: "Distro",
name: "ubuntu2204-large",
provider: Provider.Ec2OnDemand,
providerSettingsList: [
{ region: "us-east-1", instance_type: "m6i.2xlarge" },
{ region: "us-east-1", instance_type: "m5.2xlarge" },
],
hostAllocatorSettings: {
__typename: "HostAllocatorSettings",
maximumHosts: 30,
},
},
{
__typename: "Distro",
name: "ubuntu2204-static",
provider: Provider.Static,
providerSettingsList: [{ hosts: ["host-1", "host-2"] }],
hostAllocatorSettings: {
__typename: "HostAllocatorSettings",
maximumHosts: 0,
},
},
],
},
},
},
};
Loading

0 comments on commit 3b60a0d

Please sign in to comment.