Skip to content

Commit

Permalink
test: fix e2e failures for import_s3 (aws-amplify#8483)
Browse files Browse the repository at this point in the history
  • Loading branch information
jhockett authored and AmmarKarachi committed Oct 18, 2021
1 parent 9b61aad commit 5341394
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 84 deletions.
65 changes: 38 additions & 27 deletions packages/amplify-e2e-core/src/utils/headless.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,58 +9,69 @@ import {
UpdateAuthRequest,
UpdateStorageRequest,
} from 'amplify-headless-interface';
import execa from 'execa';
import execa, { ExecaChildProcess } from 'execa';
import { getCLIPath } from '..';

export const addHeadlessApi = async (cwd: string, request: AddApiRequest) => {
await executeHeadlessCommand(cwd, 'api', 'add', request);
export const addHeadlessApi = async (cwd: string, request: AddApiRequest): Promise<ExecaChildProcess<String>> => {
return await executeHeadlessCommand(cwd, 'api', 'add', request);
};

export const updateHeadlessApi = async (cwd: string, request: UpdateApiRequest) => {
await executeHeadlessCommand(cwd, 'api', 'update', request);
export const updateHeadlessApi = async (cwd: string, request: UpdateApiRequest): Promise<ExecaChildProcess<String>> => {
return await executeHeadlessCommand(cwd, 'api', 'update', request);
};

export const removeHeadlessApi = async (cwd: string, apiName: string) => {
await headlessRemoveResource(cwd, 'api', apiName);
export const removeHeadlessApi = async (cwd: string, apiName: string): Promise<ExecaChildProcess<String>> => {
return await headlessRemoveResource(cwd, 'api', apiName);
};

export const addHeadlessAuth = async (cwd: string, request: AddAuthRequest) => {
await executeHeadlessCommand(cwd, 'auth', 'add', request);
export const addHeadlessAuth = async (cwd: string, request: AddAuthRequest): Promise<ExecaChildProcess<String>> => {
return await executeHeadlessCommand(cwd, 'auth', 'add', request);
};

export const updateHeadlessAuth = async (cwd: string, request: UpdateAuthRequest) => {
await executeHeadlessCommand(cwd, 'auth', 'update', request);
export const updateHeadlessAuth = async (cwd: string, request: UpdateAuthRequest): Promise<ExecaChildProcess<String>> => {
return await executeHeadlessCommand(cwd, 'auth', 'update', request);
};

export const removeHeadlessAuth = async (cwd: string, authName: string) => {
await headlessRemoveResource(cwd, 'auth', authName);
export const removeHeadlessAuth = async (cwd: string, authName: string): Promise<ExecaChildProcess<String>> => {
return await headlessRemoveResource(cwd, 'auth', authName);
};

export const headlessAuthImport = async (cwd: string, request: ImportAuthRequest) => {
await executeHeadlessCommand(cwd, 'auth', 'import', request);
export const headlessAuthImport = async (cwd: string, request: ImportAuthRequest): Promise<ExecaChildProcess<String>> => {
return await executeHeadlessCommand(cwd, 'auth', 'import', request);
};

export const addHeadlessStorage = async (cwd: string, request: AddStorageRequest) => {
await executeHeadlessCommand(cwd, 'storage', 'add', request);
export const addHeadlessStorage = async (cwd: string, request: AddStorageRequest): Promise<ExecaChildProcess<String>> => {
return await executeHeadlessCommand(cwd, 'storage', 'add', request);
};

export const importHeadlessStorage = async (cwd: string, request: ImportStorageRequest) => {
return await executeHeadlessCommand(cwd, 'storage', 'import', request);
export const importHeadlessStorage = async (
cwd: string,
request: ImportStorageRequest,
reject: boolean = true,
): Promise<ExecaChildProcess<String>> => {
return await executeHeadlessCommand(cwd, 'storage', 'import', request, reject);
};

export const removeHeadlessStorage = async (cwd: string, request: RemoveStorageRequest) => {
await executeHeadlessCommand(cwd, 'storage', 'remove', request);
export const removeHeadlessStorage = async (cwd: string, request: RemoveStorageRequest): Promise<ExecaChildProcess<String>> => {
return await executeHeadlessCommand(cwd, 'storage', 'remove', request);
};

export const updateHeadlessStorage = async (cwd: string, request: UpdateStorageRequest) => {
await executeHeadlessCommand(cwd, 'storage', 'update', request);
export const updateHeadlessStorage = async (cwd: string, request: UpdateStorageRequest): Promise<ExecaChildProcess<String>> => {
return await executeHeadlessCommand(cwd, 'storage', 'update', request);
};

const headlessRemoveResource = async (cwd: string, category: string, resourceName: string) => {
await execa(getCLIPath(), ['remove', category, resourceName, '--yes'], { cwd });
const headlessRemoveResource = async (cwd: string, category: string, resourceName: string): Promise<ExecaChildProcess<String>> => {
return await execa(getCLIPath(), ['remove', category, resourceName, '--yes'], { cwd });
};
const executeHeadlessCommand = async (cwd: string, category: string, operation: string, request: AnyHeadlessRequest) => {
return await execa(getCLIPath(), [operation, category, '--headless'], { input: JSON.stringify(request), cwd });

const executeHeadlessCommand = async (
cwd: string,
category: string,
operation: string,
request: AnyHeadlessRequest,
reject: boolean = true,
): Promise<ExecaChildProcess<String>> => {
return await execa(getCLIPath(), [operation, category, '--headless'], { input: JSON.stringify(request), cwd, reject });
};

type AnyHeadlessRequest =
Expand Down
4 changes: 0 additions & 4 deletions packages/amplify-e2e-tests/src/__tests__/import_s3_1.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ import {
deleteProject,
deleteProjectDir,
getAppId,
getTeamProviderInfo,
initJSProjectWithProfile,
} from 'amplify-e2e-core';
import { randomizedFunctionName } from '../schema-api-directives/functionTester';
import { addEnvironmentWithImportedAuth, checkoutEnvironment, removeEnvironment } from '../environment/env';
import {
expectLocalAndCloudMetaFilesMatching,
expectLocalAndPulledBackendConfigMatching,
Expand All @@ -34,8 +32,6 @@ import {
expectLocalTeamInfoHasOnlyAuthCategoryAndNoStorage,
getS3ResourceName,
expectS3LocalAndOGMetaFilesOutputMatching,
headlessPullExpectError,
headlessPull,
} from '../import-helpers';

const profileName = 'amplify-integ-test-user';
Expand Down
24 changes: 6 additions & 18 deletions packages/amplify-e2e-tests/src/__tests__/import_s3_2.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import * as path from 'path';
import * as fs from 'fs-extra';
import { $TSObject, JSONUtilities } from 'amplify-cli-core';
import {
addAuthWithDefault,
addFunction,
addS3StorageWithSettings,
AddStorageSettings,
amplifyPull,
amplifyPushAuth,
amplifyStatus,
createNewProjectDir,
Expand All @@ -16,26 +11,19 @@ import {
getTeamProviderInfo,
initJSProjectWithProfile,
} from 'amplify-e2e-core';
import { randomizedFunctionName } from '../schema-api-directives/functionTester';
import { addEnvironmentWithImportedAuth, checkoutEnvironment, removeEnvironment } from '../environment/env';
import {
createStorageSettings,
expectLocalAndCloudMetaFilesMatching,
expectLocalAndPulledBackendConfigMatching,
getShortId,
readRootStack,
createStorageSettings,
StorageProjectDetails,
expectS3LocalAndOGMetaFilesOutputMatching,
getOGStorageProjectDetails,
importS3,
getShortId,
getStorageProjectDetails,
expectStorageProjectDetailsMatch,
removeImportedS3WithDefault,
expectNoStorageInMeta,
expectLocalTeamInfoHasOnlyAuthCategoryAndNoStorage,
getS3ResourceName,
expectS3LocalAndOGMetaFilesOutputMatching,
headlessPullExpectError,
headlessPull,
headlessPullExpectError,
importS3,
StorageProjectDetails,
} from '../import-helpers';

const profileName = 'amplify-integ-test-user';
Expand Down
64 changes: 40 additions & 24 deletions packages/amplify-e2e-tests/src/__tests__/import_s3_3.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,17 @@ describe('headless s3 import', () => {
it('import storage when no auth resource is in the project', async () => {
await initJSProjectWithProfile(projectRoot, projectSettings);

const processResult = await importHeadlessStorage(projectRoot, {
version: 1,
serviceConfiguration: {
serviceName: 'S3',
bucketName: bucketNameToImport,
const processResult = await importHeadlessStorage(
projectRoot,
{
version: 1,
serviceConfiguration: {
serviceName: 'S3',
bucketName: bucketNameToImport,
},
},
});
false,
);

expect(processResult.exitCode).toBe(1);
expect(processResult.stdout).toContain(
Expand All @@ -120,24 +124,32 @@ describe('headless s3 import', () => {
await initJSProjectWithProfile(projectRoot, projectSettings);
await addAuthWithDefault(projectRoot, {});

const processResult = await importHeadlessStorage(projectRoot, {
version: 1,
serviceConfiguration: {
serviceName: 'S3',
bucketName: bucketNameToImport,
const processResult = await importHeadlessStorage(
projectRoot,
{
version: 1,
serviceConfiguration: {
serviceName: 'S3',
bucketName: bucketNameToImport,
},
},
});
false,
);

expect(processResult.exitCode).toBe(0);
expect(processResult.stdout).toEqual('');

const processResultFail = await importHeadlessStorage(projectRoot, {
version: 1,
serviceConfiguration: {
serviceName: 'S3',
bucketName: bucketNameToImport,
const processResultFail = await importHeadlessStorage(
projectRoot,
{
version: 1,
serviceConfiguration: {
serviceName: 'S3',
bucketName: bucketNameToImport,
},
},
});
false,
);

expect(processResultFail.exitCode).toBe(1);
expect(processResultFail.stdout).toContain('Amazon S3 storage was already added to your project');
Expand All @@ -149,13 +161,17 @@ describe('headless s3 import', () => {

const fakeBucketName = `fake-bucket-name-${getShortId()}`;

const processResult = await importHeadlessStorage(projectRoot, {
version: 1,
serviceConfiguration: {
serviceName: 'S3',
bucketName: fakeBucketName,
const processResult = await importHeadlessStorage(
projectRoot,
{
version: 1,
serviceConfiguration: {
serviceName: 'S3',
bucketName: fakeBucketName,
},
},
});
false,
);

expect(processResult.exitCode).toBe(1);
expect(processResult.stdout).toContain(`The specified bucket: "${fakeBucketName}" does not exist.`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,20 @@ export class S3Service implements IS3Service {
}

public async bucketExists(bucketName: string): Promise<boolean> {
const response = await this.s3
.headBucket({
Bucket: bucketName,
})
.promise();

// If the return object has no keys then it means successful empty object was returned.
return Object.keys(response).length === 0;
try {
const response = await this.s3
.headBucket({
Bucket: bucketName,
})
.promise();
// If the return object has no keys then it means successful empty object was returned.
return Object.keys(response).length === 0;
} catch (error) {
if (error.code === 'NotFound') {
return false;
}
throw error;
}
}

public async getBucketLocation(bucketName: string): Promise<string> {
Expand All @@ -51,14 +57,12 @@ export class S3Service implements IS3Service {
Bucket: bucketName,
})
.promise();

// For us-east-1 buckets the LocationConstraint is always emtpy, we have to return a
// region in every case.
// https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLocation.html
if (response.LocationConstraint === '' || response.LocationConstraint === null) {
if (response.LocationConstraint === undefined || response.LocationConstraint === '' || response.LocationConstraint === null) {
return 'us-east-1';
}

return response.LocationConstraint;
}
}

0 comments on commit 5341394

Please sign in to comment.