Skip to content

Commit

Permalink
upcoming: [M3-8350] - Obj Gen2 - MSW, Factories, Cypress Updates (lin…
Browse files Browse the repository at this point in the history
…ode#10720)

Co-authored-by: Jaalah Ramos <[email protected]>
Co-authored-by: jdamore-linode <[email protected]>
Co-authored-by: Mariah Jacobs <[email protected]>
  • Loading branch information
4 people authored Jul 30, 2024
1 parent 1d5dde8 commit 6cb5b7a
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Upcoming Features
---

Add new MSW, Factory, and E2E intercepts for OBJ Gen2 ([#10720](https://github.com/linode/manager/pull/10720))
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @file End-to-end tests for Object Storage Access Key operations.
*/

import { createObjectStorageBucketFactory } from 'src/factories/objectStorage';
import { createObjectStorageBucketFactoryLegacy } from 'src/factories/objectStorage';
import { authenticate } from 'support/api/authentication';
import { createBucket } from '@linode/api-v4/lib/object-storage';
import {
Expand Down Expand Up @@ -120,7 +120,7 @@ describe('object storage access key end-to-end tests', () => {
it('can create an access key with limited access - e2e', () => {
const bucketLabel = randomLabel();
const bucketCluster = 'us-east-1';
const bucketRequest = createObjectStorageBucketFactory.build({
const bucketRequest = createObjectStorageBucketFactoryLegacy.build({
label: bucketLabel,
cluster: bucketCluster,
// Default factory sets `cluster` and `region`, but API does not accept `region` yet.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@

import 'cypress-file-upload';
import { createBucket } from '@linode/api-v4/lib/object-storage';
import { accountFactory, objectStorageBucketFactory } from 'src/factories';
import {
accountFactory,
createObjectStorageBucketFactoryLegacy,
createObjectStorageBucketFactoryGen1,
} from 'src/factories';
import { authenticate } from 'support/api/authentication';
import {
interceptGetNetworkUtilization,
Expand Down Expand Up @@ -55,14 +59,20 @@ const getNonEmptyBucketMessage = (bucketLabel: string) => {
*
* @param label - Bucket label.
* @param cluster - Bucket cluster.
* @param cors_enabled - Enable CORS on the bucket: defaults to true for Gen1 and false for Gen2.
*
* @returns Promise that resolves to created Bucket.
*/
const setUpBucket = (label: string, cluster: string) => {
const setUpBucket = (
label: string,
cluster: string,
cors_enabled: boolean = true
) => {
return createBucket(
objectStorageBucketFactory.build({
createObjectStorageBucketFactoryLegacy.build({
label,
cluster,
cors_enabled,

// API accepts either `cluster` or `region`, but not both. Our factory
// populates both fields, so we have to manually set `region` to `undefined`
Expand All @@ -80,14 +90,20 @@ const setUpBucket = (label: string, cluster: string) => {
*
* @param label - Bucket label.
* @param regionId - ID of Bucket region.
* @param cors_enabled - Enable CORS on the bucket: defaults to true for Gen1 and false for Gen2.
*
* @returns Promise that resolves to created Bucket.
*/
const setUpBucketMulticluster = (label: string, regionId: string) => {
const setUpBucketMulticluster = (
label: string,
regionId: string,
cors_enabled: boolean = true
) => {
return createBucket(
objectStorageBucketFactory.build({
createObjectStorageBucketFactoryGen1.build({
label,
region: regionId,
cors_enabled,

// API accepts either `cluster` or `region`, but not both. Our factory
// populates both fields, so we have to manually set `cluster` to `undefined`
Expand Down
12 changes: 11 additions & 1 deletion packages/manager/cypress/support/intercepts/object-storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { paginateResponse } from 'support/util/paginate';
import { makeResponse } from 'support/util/response';

import type {
CreateObjectStorageBucketPayload,
ObjectStorageBucket,
ObjectStorageCluster,
ObjectStorageKey,
Expand Down Expand Up @@ -86,7 +87,7 @@ export const interceptCreateBucket = (): Cypress.Chainable<null> => {
* @returns Cypress chainable.
*/
export const mockCreateBucket = (
bucket: ObjectStorageBucket
bucket: CreateObjectStorageBucketPayload
): Cypress.Chainable<null> => {
return cy.intercept(
'POST',
Expand Down Expand Up @@ -478,3 +479,12 @@ export const interceptUpdateBucketAccess = (
apiMatcher(`object-storage/buckets/${cluster}/${label}/access`)
);
};

/**
* Intercepts GET request to get object storage endpoints.
*
* @returns Cypress chainable.
*/
export const interceptGetObjectStorageEndpoints = (): Cypress.Chainable<null> => {
return cy.intercept('GET', apiMatcher(`object-storage/endpoints`));
};
63 changes: 61 additions & 2 deletions packages/manager/src/factories/objectStorage.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import Factory from 'src/factories/factoryProxy';

import type {
ObjectStorageBucket,
CreateObjectStorageBucketPayload,
ObjectStorageBucket,
ObjectStorageCluster,
ObjectStorageEndpoint,
ObjectStorageKey,
ObjectStorageObject,
} from '@linode/api-v4/lib/object-storage/types';
Expand All @@ -22,11 +23,46 @@ export const objectStorageBucketFactory = Factory.Sync.makeFactory<ObjectStorage
}
);

export const createObjectStorageBucketFactory = Factory.Sync.makeFactory<CreateObjectStorageBucketPayload>(
// TODO: OBJ Gen2 - Once we eliminate legacy and Gen1 support, we can rename this to `objectStorageBucketFactory` and set it as the default.
export const objectStorageBucketFactoryGen2 = Factory.Sync.makeFactory<ObjectStorageBucket>(
{
cluster: 'us-iad-12',
created: '2019-12-12T00:00:00',
endpoint_type: 'E3',
hostname: Factory.each(
(i) => `obj-bucket-${i}.us-iad-12.linodeobjects.com`
),
label: Factory.each((i) => `obj-bucket-${i}`),
objects: 103,
region: 'us-iad',
s3_endpoint: 'us-iad-12.linodeobjects.com',
size: 999999,
}
);

export const createObjectStorageBucketFactoryLegacy = Factory.Sync.makeFactory<CreateObjectStorageBucketPayload>(
{
acl: 'private',
cluster: 'us-east-1',
cors_enabled: true,
label: Factory.each((i) => `obj-bucket-${i}`),
}
);

export const createObjectStorageBucketFactoryGen1 = Factory.Sync.makeFactory<CreateObjectStorageBucketPayload>(
{
acl: 'private',
cors_enabled: true,
label: Factory.each((i) => `obj-bucket-${i}`),
region: 'us-east-1',
}
);

// TODO: OBJ Gen2 - Once we eliminate legacy and Gen1 support, we can rename this to `createObjectStorageBucketFactory` and set it as the default.
export const createObjectStorageBucketFactoryGen2 = Factory.Sync.makeFactory<CreateObjectStorageBucketPayload>(
{
acl: 'private',
cors_enabled: false,
endpoint_type: 'E1',
label: Factory.each((i) => `obj-bucket-${i}`),
region: 'us-east',
Expand Down Expand Up @@ -67,6 +103,21 @@ export const objectStorageKeyFactory = Factory.Sync.makeFactory<ObjectStorageKey
}
);

// TODO: OBJ Gen2 - Once we eliminate legacy and Gen1 support, we can rename this to `objectStorageKeyFactory` and set it as the default.
export const objectStorageKeyFactoryGen2 = Factory.Sync.makeFactory<ObjectStorageKey>(
{
access_key: '4LRW3T5FX5Z55LB3LYQ8',
bucket_access: null,
id: Factory.each((id) => id),
label: Factory.each((id) => `access-key-${id}`),
limited: false,
regions: [
{ endpoint_type: 'E1', id: 'us-east', s3_endpoint: 'us-east.com' },
],
secret_key: 'PYiAB02QRb53JeUge872CM6wEvBUyRhl3vHn31Ol',
}
);

export const makeObjectsPage = (
e: ObjectStorageObject[],
override: { is_truncated: boolean; next_marker: null | string }
Expand All @@ -77,3 +128,11 @@ export const makeObjectsPage = (
});

export const staticObjects = objectStorageObjectFactory.buildList(250);

export const objectStorageEndpointsFactory = Factory.Sync.makeFactory<ObjectStorageEndpoint>(
{
endpoint_type: 'E2',
region: 'us-east',
s3_endpoint: 'us-east-1.linodeobjects.com',
}
);
15 changes: 10 additions & 5 deletions packages/manager/src/mocks/serverHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
eventFactory,
firewallDeviceFactory,
firewallFactory,
objectStorageEndpointsFactory,
imageFactory,
incidentResponseFactory,
invoiceFactory,
Expand Down Expand Up @@ -60,7 +61,7 @@ import {
nodeBalancerTypeFactory,
nodePoolFactory,
notificationFactory,
objectStorageBucketFactory,
objectStorageBucketFactoryGen2,
objectStorageClusterFactory,
objectStorageKeyFactory,
objectStorageOverageTypeFactory,
Expand Down Expand Up @@ -841,6 +842,10 @@ export const handlers = [
];
return HttpResponse.json(makeResourcePage(objectStorageTypes));
}),
http.get('*/v4/object-storage/endpoints', ({}) => {
const endpoint = objectStorageEndpointsFactory.build();
return HttpResponse.json(endpoint);
}),
http.get('*object-storage/buckets/*/*/access', async () => {
await sleep(2000);
return HttpResponse.json({
Expand Down Expand Up @@ -916,11 +921,11 @@ export const handlers = [

const region = params.region as string;

objectStorageBucketFactory.resetSequenceNumber();
objectStorageBucketFactoryGen2.resetSequenceNumber();
const page = Number(url.searchParams.get('page') || 1);
const pageSize = Number(url.searchParams.get('page_size') || 25);

const buckets = objectStorageBucketFactory.buildList(1, {
const buckets = objectStorageBucketFactoryGen2.buildList(1, {
cluster: `${region}-1`,
hostname: `obj-bucket-1.${region}.linodeobjects.com`,
label: `obj-bucket-1`,
Expand All @@ -938,11 +943,11 @@ export const handlers = [
});
}),
http.get('*/object-storage/buckets', () => {
const buckets = objectStorageBucketFactory.buildList(10);
const buckets = objectStorageBucketFactoryGen2.buildList(10);
return HttpResponse.json(makeResourcePage(buckets));
}),
http.post('*/object-storage/buckets', () => {
return HttpResponse.json(objectStorageBucketFactory.build());
return HttpResponse.json(objectStorageBucketFactoryGen2.build());
}),
http.get('*object-storage/clusters', () => {
const jakartaCluster = objectStorageClusterFactory.build({
Expand Down

0 comments on commit 6cb5b7a

Please sign in to comment.