-
Notifications
You must be signed in to change notification settings - Fork 55
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
test: Package Manager Support for deploy #869
Conversation
|
@@ -115,11 +115,6 @@ void describe('create-amplify script', { concurrency: concurrency }, () => { | |||
); | |||
}); | |||
|
|||
after(async () => { | |||
// stop the npm proxy | |||
await execa('npm', ['run', 'stop:npm-proxy'], { stdio: 'inherit' }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't stop npm-proxy
because deploy.test.ts
will use it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deploy.test.ts shouldn't depend on setup from create_amplify. Each test suite should handle it's own setup and teardown. If the setup and teardown of two different test suites conflicts with each other, then we either need to run those suites serially, or figure out some other strategy for doing the setup without introducing coupling between tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, I'm thinking if we should publish locally in the GH workflow for all the e2e tests.
Setup test for each of them would be too time-consuming and expensive.
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about this problem before when I was working on initial version of canary tests and I wanted to include them in normal e2e test run too. I ended up not solving this because canaries never got included in normal e2e tests.
What we need here is to develop component that manages npm-proxy lifecycle using OS primitives or file system. The reason for this that npm test runner runs each test file as separate Node process.
On the high level what that component should do is (assuming we us fs):
- Attempt to start npm proxy or skip depending on state/lock recorded on file system (I'd use something like https://en.wikipedia.org/wiki/Double-checked_locking for that)
- When handling test start/tear down this should somehow keep record and stop npm proxy when last test tears down.
- This should be somehow resilient to inconsistent state (in case tests crash) or it should be easy to notice it and recover.
I think this piece alone deserves separate PR (which we could do on main
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One other option to solve this particular problem is to wrap node test runner cli with custom script and use programmatic api https://nodejs.org/api/test.html#runoptions . This should allow adding "before/after all test suites" logic. The advantage is that we don't have to implement cross process synchronization logic.
|
||
/** | ||
* Root test directory. | ||
*/ | ||
export const rootTestDir = fileURLToPath( | ||
new URL('./e2e-tests', import.meta.url) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move the test dir from the repo to a tmpDir so that it's a fresh new project
- name: Run E2E tests with ${{ matrix.pkg-manager }} | ||
shell: bash | ||
run: | | ||
PACKAGE_MANAGER_EXECUTABLE=${{matrix.pkg-manager}} npm run test:dir packages/integration-tests/src/test-e2e/create_amplify.test.ts | ||
PACKAGE_MANAGER_EXECUTABLE=${{matrix.pkg-manager}} npm run test:dir packages/integration-tests/src/test-e2e/deployment.test.ts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not use npm run e2e
at this moment because we'll add more test (e.g. sandbox.test.ts
) later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm assuming the end goal is to replace these with a single call to PACKAGE_MANAGER_EXECUTABLE=${{matrix.pkg-manager}} npm run e2e
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. We'll eventually use PACKAGE_MANAGER_EXECUTABLE=${{matrix.pkg-manager}} npm run e2e
when merge poc/package-manager-support
to main
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
leave the create amplify as it is and add deployment test for only npm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:-)
I'd say "leave existing e2e tests as is, create new job with matrix to run create-amplify test (with added deployment step inside test)".
protected readonly executable: string, | ||
protected readonly binaryRunner: string, | ||
protected readonly initDefault: string[], | ||
protected readonly installCommand: string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for the comment #793 (comment) in a previous PR
- name: Run E2E tests with ${{ matrix.pkg-manager }} | ||
shell: bash | ||
run: | | ||
PACKAGE_MANAGER_EXECUTABLE=${{matrix.pkg-manager}} npm run test:dir packages/integration-tests/src/test-e2e/create_amplify.test.ts | ||
PACKAGE_MANAGER_EXECUTABLE=${{matrix.pkg-manager}} npm run test:dir packages/integration-tests/src/test-e2e/deployment.test.ts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm assuming the end goal is to replace these with a single call to PACKAGE_MANAGER_EXECUTABLE=${{matrix.pkg-manager}} npm run e2e
?
@@ -115,11 +115,6 @@ void describe('create-amplify script', { concurrency: concurrency }, () => { | |||
); | |||
}); | |||
|
|||
after(async () => { | |||
// stop the npm proxy | |||
await execa('npm', ['run', 'stop:npm-proxy'], { stdio: 'inherit' }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deploy.test.ts shouldn't depend on setup from create_amplify. Each test suite should handle it's own setup and teardown. If the setup and teardown of two different test suites conflicts with each other, then we either need to run those suites serially, or figure out some other strategy for doing the setup without introducing coupling between tests.
@@ -24,5 +25,10 @@ export const createEmptyCdkProject = async ( | |||
|
|||
await cdkCli(['init', 'app', '--language', 'typescript'], projectRoot).run(); | |||
|
|||
await execa('npm', ['install', '-D', '@aws-amplify/auth-construct-alpha'], { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doesn't seem like it belongs in "create_empty_cdk_project". Maybe it should be part of the createProject
method in AuthTestCdkProjectCreator
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can skip "raw cdk tests" in project manager expansion and just test them with npm.
The reason is that these tests are only focused on our L3 constructs and we'd be just testing CDK CLI here.
@@ -29,5 +35,24 @@ export const createEmptyAmplifyProject = async ( | |||
|
|||
await setupDirAsEsmModule(projectAmplifyDir); | |||
|
|||
await execa( | |||
packageManagerProps?.executable ?? 'npm', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is going to be a repeated pattern, we may need a PackageManagerController abstraction for the test suite. It would be similar to the one in create-amplify
but hopefully more lightweight to cover the installing that we need to do in tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1.
Other feedback is:
Do we need to "install" these or is there npm link
equivalent we could use ? Or perhaps this was working because we were under single mono repo so packages were resolved automagically ?
Perhaps this is right approach but I wonder why we didn't do this before.
Btw.
If this file becomes sibling of create-amplify
perhaps we should just run create-amplify
and then substitute sources of generated project?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was working before because the test directories were created in the project repo so "automagic resolution" happened. Personally I'm not opposed to keeping it that way so that we don't waste test time installing the same packages over and over
'@aws-amplify/backend', | ||
'@aws-amplify/backend-cli', | ||
'@aws-amplify/auth-construct-alpha', | ||
'@aws-amplify/backend-deployer', | ||
...(projectDirName === 'data-storage-auth' | ||
? ['uuid', '@types/uuid'] | ||
: []), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How much, if any, of this belongs in "create_empty_amplify_project"? I can buy that installing backend and backend-cli should belong here, but not so sure about the other stuff. Perhaps individual tests should install those packages if needed.
}; | ||
default: | ||
throw new Error( | ||
`Unknown package manager executable: ${PACKAGE_MANAGER_EXECUTABLE}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is never going to hit since the assignment on line 5 assigns a default of "npm". Probably better to throw than assign a default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we spoke offline but recording here too.
Please remember that deployer
also uses npx
to run CDK CLI and TSC.
I suggest to spike that part first and get tests passing with deployer
covered somehow and then figure out how Gen 2 CLI -> deployer
should communicate to pass package manager information and how abstractions there and in tests should look like.
export const rootTestDir = fileURLToPath( | ||
new URL('./e2e-tests', import.meta.url) | ||
); | ||
export const rootTestDir = path.join(os.tmpdir(), 'e2e-tests'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have to say that I like when test project appear somewhere repo root (like it was before here).
The reason is that when I work on these tests locally I can inspect the output within the same IDE instance and I don't have to jump over to OS temp dir.
Perhaps common ground could be to keep e2e-tests
where they are but perhaps add some path segment per test session.
I.e. e2e-tests/<some_uuid>/<rest>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw. If we decide to follow suggestion to bootstrap test projects using create-amplify
then perhaps we should make change as suggested and create folder outside of repo root.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
then perhaps we should make change as suggested and create folder outside of repo root.
I'm confused. Did you suggest to create the test folder inside our outside of the repo root?
The reason why I changed it to a tmpDir was because if it's in the repo root, it shares the node_modules with the repo, which might hide some potential issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realized later that if we want to "install" or use "create amplify" then it might be better to have test projects outside of repo root because of what you mentioned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we decide to use the repo root and share the node_modules, we should be able to remove the install commands in this PR.
Also, we may not need to use npx-proxy
, so we don't have to make that change in the PR either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm in favor of leaving test dirs within the repo root and not doing the extra installation bits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
on the other hand we should figure out what we want to test.
if we want to test that deployer works with "yarn resolved" workspace then perhaps going through full process makes some sense.
On the other hand it seems that we perhaps don't have to run every test project to assert that deployer works with each package manager.
So perhaps an option to consider is to have separate e2e "deployment test" that explores one deployment scenario but runs with multiple package managers.
Or maybe we should just add deployement step to create amplify tests and leave deployment tests as they are.
@@ -115,11 +115,6 @@ void describe('create-amplify script', { concurrency: concurrency }, () => { | |||
); | |||
}); | |||
|
|||
after(async () => { | |||
// stop the npm proxy | |||
await execa('npm', ['run', 'stop:npm-proxy'], { stdio: 'inherit' }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about this problem before when I was working on initial version of canary tests and I wanted to include them in normal e2e test run too. I ended up not solving this because canaries never got included in normal e2e tests.
What we need here is to develop component that manages npm-proxy lifecycle using OS primitives or file system. The reason for this that npm test runner runs each test file as separate Node process.
On the high level what that component should do is (assuming we us fs):
- Attempt to start npm proxy or skip depending on state/lock recorded on file system (I'd use something like https://en.wikipedia.org/wiki/Double-checked_locking for that)
- When handling test start/tear down this should somehow keep record and stop npm proxy when last test tears down.
- This should be somehow resilient to inconsistent state (in case tests crash) or it should be easy to notice it and recover.
I think this piece alone deserves separate PR (which we could do on main
).
@@ -24,5 +25,10 @@ export const createEmptyCdkProject = async ( | |||
|
|||
await cdkCli(['init', 'app', '--language', 'typescript'], projectRoot).run(); | |||
|
|||
await execa('npm', ['install', '-D', '@aws-amplify/auth-construct-alpha'], { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can skip "raw cdk tests" in project manager expansion and just test them with npm.
The reason is that these tests are only focused on our L3 constructs and we'd be just testing CDK CLI here.
@@ -29,5 +35,24 @@ export const createEmptyAmplifyProject = async ( | |||
|
|||
await setupDirAsEsmModule(projectAmplifyDir); | |||
|
|||
await execa( | |||
packageManagerProps?.executable ?? 'npm', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1.
Other feedback is:
Do we need to "install" these or is there npm link
equivalent we could use ? Or perhaps this was working because we were under single mono repo so packages were resolved automagically ?
Perhaps this is right approach but I wonder why we didn't do this before.
Btw.
If this file becomes sibling of create-amplify
perhaps we should just run create-amplify
and then substitute sources of generated project?
@@ -25,6 +25,11 @@ export const setupDirAsEsmModule = async (absoluteDirPath: string) => { | |||
'es2022', | |||
]; | |||
|
|||
await execa('npm', ['install', 'typescript'], { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
npm
only ?;-)
I think this is another signal to just use create-amplify to boostrap test project.
As discussed, I'm closing the PR and create a new PR to add deployment step for in the create amplify test |
Problem
Setup e2e test with supported Package Managers (npm, yarn-classic, yarn-modern, pnpm) for
amplify deploy
.Issue number, if available:
Changes
Major change
deployment.test.ts
withPACKAGE_MANAGER_EXECUTABLE
Other changes
./
to a temporary foldertmp
to create a fresh projectstop:npm-proxy
Corresponding docs PR, if applicable:
Validation
Validating in the PR check
Checklist
run-e2e
label set.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.