Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Automated testcase for creating a bucket with cache and multids #70

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cypress/constants/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ export const STATUS_CARD_TITLE = 'Data Federation service';

// Bucket policy
export const SINGLE_BUCKET_POLICY = 'e2e-bucket-single';
export const SINGLE_BUCKET_POLICY_WITH_CACHE = 'e2e-bucket-single-cache';
export const MULTIPLE_BUCKET_POLICY = 'e2e-bucket-multiple';
export const PVC_NAME = 'e2e-pvc';
export const DATA_SOURCE_NAME_NSFS = 'e2e-nsfs-data-source';
export const DATA_SOURCE_NAME_AWS = 'e2e-aws-data-source';

// constants for data source test cases
export const TEST_DATA_SOURCE = 'testing-data-source';
export const TEST_READ_DATA_SOURCE = 'testing-data-source-read';
export enum Providers {
AWS = 'AWS S3',
AZURE = 'Azure Blob',
Expand All @@ -26,6 +29,7 @@ export const DATA_SOURCE_INPUTS = {
accessKey: Cypress.env('AWS_ACCESS_KEY_ID'),
secretKey: Cypress.env('AWS_SECRET_ACCESS_KEY'),
targetBucket: Cypress.env('AWS_SINGLE_DATA_SOURCE_BUCKET'),
targetwriteBucket: Cypress.env('AWS_SINGLE_WRITE_DATA_SOURCE_BUCKET'),
};

// Helper constants.
Expand Down
121 changes: 81 additions & 40 deletions cypress/tests/bucket-policy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@ import {
SINGLE_BUCKET_POLICY,
PVC_NAME,
DATA_SOURCE_NAME_NSFS,
SINGLE_BUCKET_POLICY_WITH_CACHE,
TEST_DATA_SOURCE,
MULTIPLE_BUCKET_POLICY,
TEST_READ_DATA_SOURCE,
} from '../constants/tests';
import { dataSourceNSFS } from '../mocks/data-source';
import { BPCommon } from '../views/bucket-policy';
import { projectNameSpace } from '../views/common';
import { deleteDataSourceResources } from '../views/data-resource';
import { MCGMSCommon } from '../views/mcg-ms-common';
import { pvc } from '../views/pvc';

describe('Bucket policy page', () => {
describe('Bucket policy creation of nsfs type', () => {
before(() => {
cy.login();
cy.clickNavLink(['Storage', 'PersistentVolumeClaims']);
Expand Down Expand Up @@ -38,57 +44,92 @@ describe('Bucket policy page', () => {
failOnNonZeroExit: false,
});
});

cy.logout();
});

// ToDo(Sanjal): Need to refactor and add more test blocks for "Multi" and "Cache" types as well.
// right now we are only creating "nsfs" (FileSystem) type NamespaceStore which is only allowed with BucketClass of type "Single".
it('creates Bucket policy with single data source', () => {
// ToDo(Sanjal): Need to refactor and add more test blocks for "Multi" and "Cache" types as well.
// right now we are only creating "nsfs"(FileSystem) type NamespaceStore which is only allowed with BucketClass of type "Single".
it('creates Bucket policy with single data source of nsfs type', () => {
cy.exec(
`echo '${JSON.stringify(
dataSourceNSFS(DATA_SOURCE_NAME_NSFS, PVC_NAME, 'e2e-subPath')
)}' | oc create -f -`
).then(() => {
cy.byTestID('item-create').click();
cy.byTestID('bucket-name-text').type(SINGLE_BUCKET_POLICY);
cy.byTestID('read-write-dropdown')
.should('be.visible')
.find('button')
.first()
.click();
cy.contains(DATA_SOURCE_NAME_NSFS).click();
cy.byTestID('namespace-dropdown')
.should('be.visible')
.contains(DATA_FEDERATION_NAMESPACE);
cy.log('Create bucket policy');
cy.byTestID('confirm-action-bucket').click();
cy.log('Verify bucket policy created');
cy.byTestSelector('details-item-value__Name').should(
'contain',
SINGLE_BUCKET_POLICY
BPCommon.createUsingSingleDSAndExistingDataSource(
SINGLE_BUCKET_POLICY,
DATA_SOURCE_NAME_NSFS
);
cy.log('Verify bucket policy is Ready');
cy.byTestID('status-text').should('contain', 'Ready');
cy.log('Verify only 1 data source is connected');
cy.byTestID('mcg-resource-popover')
.should('be.visible')
.should('contain', '1 data source');
cy.log('Verify name of the connected data source');
cy.byTestID('mcg-resource-popover').should('be.visible').click();
cy.contains(DATA_SOURCE_NAME_NSFS);
cy.log('Verify if OBC is created or not');
cy.byTestID('obc-resource-popover')
.should('be.visible')
.should('contain', '1 ObjectBucketClaim');
BPCommon.confirmCreateBucket();
BPCommon.checkBucketCreation(SINGLE_BUCKET_POLICY, DATA_SOURCE_NAME_NSFS);
});
});

it('deletes created Bucket policy', () => {
cy.byTestID(SINGLE_BUCKET_POLICY).first().click();
cy.byTestID('details-actions').find('button').click();
cy.byTestID('details-actions').find('li').last().click();
cy.byTestID('delete-action').click();
cy.byTestID(SINGLE_BUCKET_POLICY).should('not.exist');
BPCommon.deleteFromDetailsPage(SINGLE_BUCKET_POLICY);
});
});

describe('Bucket policy creation with single data source and enabled cache', () => {
before(() => {
cy.login();
});

beforeEach(() => {
MCGMSCommon.visitBucketPolicyList();
});

after(() => {
/**
* Need some time for BucketClass to get cleaned-up properly before deleting NamespaceStore,
* else we get an error from server: admission webhook "admissionwebhook.noobaa.io" denied the request:
* cannot complete because nsr "-data-source" in "IN_USE" state.
* Even though BucketClass is actually deleted, there is some deplay for it to get reflected for NamespaceStore.
*/
cy.wait(30 * SECOND);
deleteDataSourceResources(TEST_DATA_SOURCE, DATA_FEDERATION_NAMESPACE);
cy.logout();
});

it('creates Bucket policy with single data source and enabled cache', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please have a look into this PR Idea is to bring out common stuff into a separate file as we have to the data source.

@alfonsomthd what is your opinion regarding this, should we have a common separate file?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree on code reuse: let's move the common logic to a helper method on the appropriate helper file.

BPCommon.createUsingSingleDSAndNewDataSource(
SINGLE_BUCKET_POLICY_WITH_CACHE,
TEST_DATA_SOURCE
);
cy.log('Enable Cache');
cy.byTestID('enable-cache-checkbox').should('be.visible').check();
BPCommon.confirmCreateBucket();
BPCommon.checkBucketCreation(SINGLE_BUCKET_POLICY, TEST_DATA_SOURCE);
});

it('deletes created Bucket policy', () => {
BPCommon.deleteFromDetailsPage(SINGLE_BUCKET_POLICY_WITH_CACHE);
});
});

describe('Bucket policy creation with multiple data sources', () => {
before(() => {
cy.login();
});
beforeEach(() => {
MCGMSCommon.visitBucketPolicyList();
});
after(() => {
/**
* Need some time for BucketClass to get cleaned-up properly before deleting NamespaceStore,
* else we get an error from server: admission webhook "admissionwebhook.noobaa.io" denied the request:
* cannot complete because nsr "data-source" in "IN_USE" state.
* Even though BucketClass is actually deleted, there is some deplay for it to get reflected for NamespaceStore.
*/
cy.wait(30 * SECOND);
deleteDataSourceResources(TEST_READ_DATA_SOURCE, DATA_FEDERATION_NAMESPACE);
cy.logout();
});
it('creates Bucket policy with multiple data sources', () => {
BPCommon.createUsingMultiDS(MULTIPLE_BUCKET_POLICY, TEST_READ_DATA_SOURCE);
BPCommon.confirmCreateBucket();
BPCommon.checkBucketCreation(MULTIPLE_BUCKET_POLICY, TEST_READ_DATA_SOURCE);
});
it('deletes created Bucket policy', () => {
BPCommon.deleteFromDetailsPage(MULTIPLE_BUCKET_POLICY);
});
});
30 changes: 25 additions & 5 deletions cypress/tests/data-source.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,39 @@ describe('data source creation', () => {

it('creates a data source having AWS as the provider', () => {
cy.onlyOn(AWS_CREDS_EXIST);
createDataSource(Providers.AWS, TEST_DATA_SOURCE);
createDataSource(
Providers.AWS,
TEST_DATA_SOURCE,
DATA_SOURCE_INPUTS.targetBucket
);
checkDataSourceCreation(TEST_DATA_SOURCE, DATA_FEDERATION_NAMESPACE);
cy.byTestID(`status-text`).should('contain', 'Ready');
});

it('creates a data source having S3 Compatible as the provider', () => {
createDataSource(Providers.S3, TEST_DATA_SOURCE);
createDataSource(
Providers.S3,
TEST_DATA_SOURCE,
DATA_SOURCE_INPUTS.targetBucket
);
checkDataSourceCreation(TEST_DATA_SOURCE, DATA_FEDERATION_NAMESPACE);
});

it('creates a data source having Azure Blob as the provider', () => {
createDataSource(Providers.AZURE, TEST_DATA_SOURCE);
createDataSource(
Providers.AZURE,
TEST_DATA_SOURCE,
DATA_SOURCE_INPUTS.targetBucket
);
checkDataSourceCreation(TEST_DATA_SOURCE, DATA_FEDERATION_NAMESPACE);
});

it('creates a data source having IBM COS as the provider', () => {
createDataSource(Providers.IBM, TEST_DATA_SOURCE);
createDataSource(
Providers.IBM,
TEST_DATA_SOURCE,
DATA_SOURCE_INPUTS.targetBucket
);
checkDataSourceCreation(TEST_DATA_SOURCE, DATA_FEDERATION_NAMESPACE);
});
});
Expand All @@ -69,7 +85,11 @@ describe('data source deletion', () => {
MCGMSCommon.visitDataSourceListPage();
navigateToCreatePage();
app.waitForLoad();
createDataSource(Providers.AWS, TEST_DATA_SOURCE);
createDataSource(
Providers.AWS,
TEST_DATA_SOURCE,
DATA_SOURCE_INPUTS.targetBucket
);
checkDataSourceCreation(TEST_DATA_SOURCE, DATA_FEDERATION_NAMESPACE, false);
});

Expand Down
113 changes: 113 additions & 0 deletions cypress/views/bucket-policy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { DATA_FEDERATION_NAMESPACE } from '../constants/common';
import { DATA_SOURCE_INPUTS, Providers } from '../constants/tests';
import { createDataSource } from './data-resource';

export const BPCommon = {
createUsingSingleDSAndExistingDataSource: (
bucketName: string,
dataSourceName: string
) => {
cy.log(`creating bucket ${bucketName}`);
cy.byTestID('item-create').click();
cy.log(`entering bucket name as ${bucketName}`);
cy.byTestID('bucket-name-text').type(bucketName);
cy.byTestID('read-write-dropdown')
.should('be.visible')
.find('button')
.first()
.click();
cy.log(`Creating new data source`);
cy.contains(dataSourceName).click();
},
createUsingSingleDSAndNewDataSource: (
bucketName: string,
dataSourceName: string
) => {
cy.log(`creating bucket ${bucketName}`);
cy.byTestID('item-create').click();
cy.log(`entering bucket name as ${bucketName}`);
cy.byTestID('bucket-name-text').type(bucketName);
cy.byTestID('read-write-dropdown')
.should('be.visible')
.find('button')
.first()
.click();
cy.log(`Creating new data source`);
cy.byTestID('add-data-source-item').click();
createDataSource(
Providers.AWS,
dataSourceName,
DATA_SOURCE_INPUTS.targetBucket
);
cy.byTestID('ready-action-finish').click();
cy.byTestID('read-write-dropdown')
.should('be.visible')
.find('button')
.first()
.click();
cy.byTestID('data-source-selection-item').find('li').last().click();
},
confirmCreateBucket: () => {
cy.byTestID('namespace-dropdown')
.should('be.visible')
.contains(DATA_FEDERATION_NAMESPACE);
cy.log('Create bucket policy');
cy.byTestID('confirm-action-bucket').click();
},
createUsingMultiDS: (bucketName: string, dataSourceName: string) => {
cy.log(`creating bucket ${bucketName}`);
cy.byTestID('item-create').click();
cy.log(`entering bucket name as ${bucketName}`);
cy.byTestID('bucket-name-text').type(bucketName);
cy.byTestID('multi-data-source-radio-button').click();
cy.byTestID('read-dropdown').click();
cy.log(`Configuring a data source to read`);
cy.byTestID('data-source-selection-item').click();
cy.byTestID('add-data-source-item').click();
createDataSource(
Providers.AWS,
dataSourceName,
DATA_SOURCE_INPUTS.targetBucket
);
cy.byTestID('ready-action-finish').click();
cy.byTestID('read-dropdown').should('be.visible').first().click();
cy.byTestID('data-source-selection-item')
.find('li')
.byTestID(`${dataSourceName}-dropdown-item`)
.find('input[type=checkbox]')
.check();
cy.byTestID('read-dropdown').first().click();
cy.byTestID('write-dropdown').find('button').click();
cy.log(`Configuring a data source to write`);
cy.byTestID('data-source-selection-item')
.find('li')
.byTestID(`${dataSourceName}-dropdown-item`)
.click();
cy.byTestID('write-dropdown').should('be.visible').first().click();
},
checkBucketCreation: (bucketName: string, dataSourceName: string) => {
cy.log('Verify bucket policy created');
cy.byTestSelector('details-item-value__Name').should('contain', bucketName);
cy.log('Verify bucket policy is Ready');
cy.byTestID('status-text').should('contain', 'Ready');
cy.log('Verify only 1 data source is connected');
cy.byTestID('mcg-resource-popover')
.should('be.visible')
.should('contain', '1 data source');
cy.log('Verify name of the connected data source');
cy.byTestID('mcg-resource-popover').should('be.visible').click();
cy.contains(dataSourceName);
cy.log('Verify if OBC is created or not');
cy.byTestID('obc-resource-popover')
.should('be.visible')
.should('contain', '1 ObjectBucketClaim');
},
deleteFromDetailsPage: (bucketName: string) => {
cy.log(`deleting bucket ${bucketName}`);
cy.byTestID(bucketName).first().click();
cy.byTestID('details-actions').find('button').click();
cy.byTestID('details-actions').find('li').last().click();
cy.byTestID('delete-action').click();
cy.byTestID(bucketName).should('not.exist');
},
};
9 changes: 5 additions & 4 deletions cypress/views/data-resource.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { MINUTE, SECOND } from '../constants/common';
import { DATA_SOURCE_INPUTS, Providers } from '../constants/tests';

const inputCustomSecrets = () => {
const { accessKey, secretKey, targetBucket } = DATA_SOURCE_INPUTS;
const inputCustomSecrets = (targetBucket: string) => {
const { accessKey, secretKey } = DATA_SOURCE_INPUTS;
cy.log('setting up custom secret for the resource');
cy.byTestID('switch-to-credentials').click();
cy.byTestID(`namespacestore-access-key`).type(accessKey);
Expand Down Expand Up @@ -86,13 +86,14 @@ export const navigateToListPageViaBreadCrumbs = (dataSourceName: string) => {

export const createDataSource = (
provider: Providers,
dataSourceName: string
dataSourceName: string,
bucketName: string
) => {
cy.log(`creating data source with ${provider} as provider`);
cy.log(`entering data source name as ${dataSourceName}`);
cy.byTestID(`data-source-name`).type(dataSourceName);
setUpProvider(provider);
inputCustomSecrets();
inputCustomSecrets(bucketName);
cy.byTestID(`data-source-create-button`).click();
};

Expand Down
3 changes: 3 additions & 0 deletions packages/components/bucket-policy/data-resource-dropdowns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const DataResourceDropdown: React.FC<DataResourceDropdownProps> = ({
key="data-source-add-modal"
className="create-data-source__modal-button"
variant="plain"
data-test="add-data-source-item"
onClick={() => {
setOpen(false);
launchModal();
Expand All @@ -87,6 +88,7 @@ const DataResourceDropdown: React.FC<DataResourceDropdownProps> = ({
className={classNames(props?.className)}
variant={variant}
aria-label={t('Select a data source')}
data-test="data-source-selection-item"
onToggle={setOpen}
onSelect={(e, selection) => {
onChange(selection as string);
Expand Down Expand Up @@ -132,6 +134,7 @@ export const SingleDataResource: React.FC<DataResourceProps> = ({
<Checkbox
id="cache-checkbox"
label={t('Enable cache')}
data-test="enable-cache-checkbox"
onChange={(checked) =>
dispatch({
type: BucketPolicyActionType.SET_CACHE,
Expand Down