Skip to content

refactor: replace log,exit in utils of init,addons command #3382

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

Merged
merged 5 commits into from
Sep 23, 2021

Conversation

tinfoil-knight
Copy link
Contributor

- Summary

#3028 was too large for review and is being broken down.

This PR is a follow-up on #3247 and uses the separate logging and process control utilities created in it to remove the inherited ones.

This PR focuses mostly on utilities related to the init,addons commands. Changes are a bit sparse and not contained in a specific command folder like the previous PRs.

Also the detectAwsSdkError function in src/lib/functions/utils.js was unused and has been removed in a separate commit. If this change was not supposed to be made (or be done in a separate PR), we could just remove that commit.

This should be the last PR needed to close PR #3028 and issue #2728.

- Test plan

npx ava --verbose --serial

// a stub utility is used in tests
const warn = warnLog || warn_
// a stub utility is used in tests for warn
const loadDotEnvFiles = async function ({ projectDir, warn = warn_ }) {
Copy link
Contributor

@ehmicky ehmicky Sep 22, 2021

Choose a reason for hiding this comment

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

Should the argument warn be removed altogether?

It seems like the reason this is here is because dot-env.test.js is mocking warn(). This is probably to remove warning messages printed during tests. However, mocking seems the wrong way to solve this, as it would not scale well: many test files would need to mock warn().

Based on this, what are your thoughts on the following?

  • Removing the warnLog/warn argument from this function.
  • Import the warn utility directly instead
  • In dot-env.test.js, do not pass any warn stub

Additionally, splitting the function into two as suggested above could help removing the warning message from the unit tests.

(Note: this specific change might deserve its own PR)

Copy link
Contributor Author

@tinfoil-knight tinfoil-knight Sep 22, 2021

Choose a reason for hiding this comment

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

I'd definitely like to remove the warn argument.

Internally in @oclif/errors, warn relies on console.error for logging but I don't think we should rely on that to change the global object.

Also, AFAIK in some places the logs are tested which means that we can't use the test environment flag to disable them.
(But, we could use an alternate environment variable which can be set before tests that require logging to be disabled and removed during cleanup.)

In dot-env.test.js, do not pass any warn stub

I went through the tests and they only seem to be checking the results. Why was warn being suppressed in that case?

Additionally, splitting the function into two as suggested above could help removing the warning message from the unit tests.

Yeah. We could do this.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why was warn being suppressed in that case?

My guess is that this was to remove the verbosity of the console output when running tests. However, splitting the logging logic to a parent function would allow the tests to import the core logic without printing any log messages.

@@ -28,7 +28,8 @@ const DEFAULT_HTTPS_PORT = 443
// 50 seconds
const AGENT_PORT_TIMEOUT = 50

const getAgent = async ({ httpProxy, certificateFile, exit }) => {
// a stub utility is used in tests for exit
const getAgent = async ({ httpProxy, certificateFile, exit = exit_ }) => {
Copy link
Contributor

@ehmicky ehmicky Sep 22, 2021

Choose a reason for hiding this comment

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

There might be some opportunity to improve how this function is being tested.

At the moment, we mock exit, although we don't really need to. Instead, we could split getAgent() into two functions:

  • tryGetAgent({ httpProxy, certificateFile }), returning an object either { agent } (success) or { agent, warning: 'warning message' } or { error: 'error message' }
  • getAgent({ httpProxy, certificateFile }), the top-level function, would call tryGetAgent(). If it returns:
    • an error, it would log() it with NETLIFYDEVERR and call exit(1)
    • a warning, it would log() it with NETLIFYDEVWARN but not exit()
    • an agent, it would return it

This approach would have the benefits of:

  • Decoupling logging/exiting from the main actual logic
  • Removing the need to mock exit() in the unit tests, since those could test tryGetAgent() instead

What do you think?

(Note: this specific change might deserve its own PR)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it's better to check function responses rather than the behaviour of process control and logging utilities.

One thing is that it'd create an export which won't be used anywhere except for the tests. Is that okay?

Copy link
Contributor

@ehmicky ehmicky Sep 22, 2021

Choose a reason for hiding this comment

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

One thing is that it'd create an export which won't be used anywhere except for the tests. Is that okay?

I think this is a side effect of unit testing (as opposed to integration testing). Since we are testing at a small scale, we sometimes need to hook into specific functions, i.e. create exports for them just for testing purpose.

Even if we were to enforce not creating exports just for unit tests, we would still do something quite similar: we would let test files import production files that are not imported directly by end users. To illustrate how this is in essence the same thing: in the case above, we could theoretically split those two functions into separate files, so that the unit test does not create a new export (although that'd be artificial).

I think it's the nature of unit testing to break encapsulation for testing purpose. It's also its major drawback (making it more brittle and implementation-specific) but also advantage (making it simpler), compared to integration testing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Gotcha!

@tinfoil-knight tinfoil-knight changed the title refactor: replace log,exit in utils of init,addons command; remove detectAwsSdkError refactor: replace log,exit in utils of init,addons command Sep 22, 2021
@tinfoil-knight
Copy link
Contributor Author

@ehmicky I'm guessing we're making the suggested changes in another PR as mentioned in the comments or are any changes needed in this one itself?

@ehmicky
Copy link
Contributor

ehmicky commented Sep 23, 2021

I would think of splitting the dot-env.js and http-agent.js into 2 separate PRs. But the other changes in this PR are still good to go (after removing those two files' changes)?

@ehmicky ehmicky added automerge Add to Kodiak auto merge queue type: chore work needed to keep the product and development running smoothly labels Sep 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge Add to Kodiak auto merge queue type: chore work needed to keep the product and development running smoothly
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants