GithubHelp home page GithubHelp logo

node-test-utilities's Introduction

New Relic Open Source community project banner.

New Relic Test Utilities

npm status badge Test Utilities CI codecov

Library full of test utilities and helpers for New Relic instrumentation modules. The full documentation for this module can be found on GitHub.

Installation

It can be installed and used as such:

npm install @newrelic/test-utilities
// index.js
require('@newrelic/test-utilities')

Usage

TestAgent Helper

The TestAgent class helps set up a New Relic agent suitable for tests. With this you can run your tests within transactions without having to actually set up a full New Relic application. The helper should be created and torn down for each test to ensure you are running in a clean environment each time. In tap this may look like this:

tap.test('some test suite', (t) => {
  let helper = null
  t.beforeEach((done) => {
    helper = utils.TestAgent.makeInstrumented()
    done()
  })

  t.afterEach((done) => {
    helper && helper.unload()
    done()
  })

  t.test('test 1', (t) => {
    helper.runInTransaction((tx) => {
      // Your test is now in transaction context and normal instrumentation
      // logic should occur.
    })
  })
})

Assertions

There are a number of assertions provided to help write your tests. Each of these assertions can either be used directly (utils.assert.segments(...)) or as tap tests (t.segments(...)). In the direct use case they will throw exceptions, and thus can be used like any other assertion library. Here are a few examples of using them:

let tap = require('tap')
let utils = require('@newrelic/test-utilities')

// This adds all the assertions to tap's `Test` class.
utils.assert.extendTap(tap)

tap.test((t) => {
  let helper = utils.TestAgent.makeInstrumented()
  t.tearDown(() => helper.unload())

  helper.runInTransaction((tx) => {
    // Do some testing logic...

    // This will check that transaction state hasn't been lost and that the given
    // transaction is the currently active one. A good check to make in the
    // callbacks to asynchronous methods.
    t.transaction(tx, 'should be in correct context')

    // This will check that the transaction trace has the segment structure you
    // describe. Extra segments in the trace are allowed.
    t.segments(tx.trace.root, [{name: 'mysegment'}], 'should have expected segments')

    // Like above, this checks the structure of the trace against the one you
    // describe but they must exactly match. Any extra segments in the trace are
    // considered a failure.
    t.exactSegments(tx.trace.root, [{name: 'mysegment'}], 'should have expected segments')

    // Many metrics are not created until the transaction ends, if you're
    // missing metrics in your instrumentation tests, this may help.
    tx.end()

    // This will check that the metrics given have been created. Extra metrics
    // are allowed.
    t.metrics(['/My/Metric'], 'should have created metrics')

    // Like above, this checks that the given metrics were created. Any extra
    // metrics that were created are considered a failure.
    t.exactMetrics(['/My/Metric', '/Another/Metric'], 'should have exactly these metrics')
  })
})

Versioned Tests

The versioned-tests script can be used to execute a series of tests against several versions of dependencies. For example, the command below would run all the tests suffixed with .tap.js against every minor version of the specified dependencies.

$ versioned-tests --minor tests/versioned/*.tap.js

The following command will run only those test files whose names include the keyword redis:

$ versioned-tests tests/versioned/ -P redis

You can then specify the versions you want to run this against by adding a package.json file in your tests directory. This package file should have a tests array describing each suite. For example, the one shown below will test different files for each version of mongodb from v1.0.0 through to the latest.

{
  "name": "mongodb-tests",
  "version": "0.0.0",
  "private": true,
  "tests": [
    {
      "engines": {
        "node": ">=0.10 <7"
      },
      "dependencies": {
        "mongodb": "^1"
      },
      "files": [
        "v1-tests.tap.js"
      ]
    },
    {
      "engines": {
        "node": ">=0.10"
      },
      "dependencies": {
        "mongodb": ">=2.1 <3"
      },
      "files": [
        "v2-tests.tap.js",
        "shared-tests.tap.js"
      ]
    },
    {
      "engines": {
        "node": ">=4"
      },
      "dependencies": {
        "mongodb": ">=3"
      },
      "files": [
        "v3-tests.tap.js",
        "shared-tests.tap.js"
      ]
    }
  ]
}

The versioned tests runner has a timeout for tests that defaults to one minute. That is, if running a test -- including installing its dependencies! -- takes longer than a minute, then that test is considered to have failed. You can change this timeout with the TEST_CHILD_TIMEOUT environment variable, which is interpreted as a number of milliseconds. For example, to set a test timeout of ten minutes, you could invoke the test runner like this:

$ TEST_CHILD_TIMEOUT=600000 versioned-tests

As ten minutes is 600,000 milliseconds.

Testing

The module includes a suite of unit and functional tests which should be used to verify that your changes don't break existing functionality.

All tests are stored in tests/ and are written using Node-Tap with the extension .tap.js.

To run the full suite, run: npm test.

Individual test scripts include:

npm run lint
npm run unit

Support

Should you need assistance with New Relic products, you are in good hands with several support channels.

If the issue has been confirmed as a bug or is a feature request, please file a GitHub issue.

Support Channels

Privacy

At New Relic we take your privacy and the security of your information seriously, and are committed to protecting your information. We must emphasize the importance of not sharing personal data in public forums, and ask all users to scrub logs and diagnostic information for sensitive information, whether personal, proprietary, or otherwise.

We define “Personal Data” as any information relating to an identified or identifiable individual, including, for example, your name, phone number, post code or zip code, Device ID, IP address and email address.

For more information, review New Relic’s General Data Privacy Notice.

Contribute

We encourage your contributions to improve New Relic Test Utilities! Keep in mind when you submit your pull request, you'll need to sign the CLA via the click-through using CLA-Assistant. You only have to sign the CLA one time per project.

If you have any questions, or to execute our corporate CLA, required if your contribution is on behalf of a company, please drop us an email at [email protected].

A note about vulnerabilities

As noted in our security policy, New Relic is committed to the privacy and security of our customers and their data. We believe that providing coordinated disclosure by security researchers and engaging with the security community are important means to achieve our security goals.

If you believe you have found a security vulnerability in this project or any of New Relic's products or websites, we welcome and greatly appreciate you reporting it to New Relic through Hacour bug bounty program.

If you would like to contribute to this project, review these guidelines.

To all contributors, we thank you! Without your contribution, this project would not be what it is today. We also host a community project page dedicated to New Relic Node Test Utilities.

License

New Relic Test Utilities is licensed under the Apache 2.0 License.

New Relic Test Utilities also uses source code from third-party libraries. You can find full details on which libraries are used and the terms under which they are licensed in the third-party notices document.

node-test-utilities's People

Contributors

astormnewrelic avatar bizob2828 avatar carlo-808 avatar coreyarnold avatar dependabot[bot] avatar garbados avatar github-actions[bot] avatar jmartin4563 avatar jordigh avatar jsumners-nr avatar lykkin avatar michaelgoin avatar mlong-nr avatar mrickard avatar nataliewolfe avatar nijotz avatar paperclypse avatar psvet avatar snyk-bot avatar svetlanabrennan avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-test-utilities's Issues

The versioned runner filters out versions when running with --major and constrained dep versions

Description

It was discovered that certain modules run with the version as latest or >=x.x.x <x.x.x when the --major flag is being used and the version range is outside the latest version in the semver major line.

Expected Behavior

It should take the version range in package.json into consideration before filtering out the valid version.

Note: The runner still DTRT because when it goes to npm install it uses the semver range but it impacts displaying the exact version being run.

Relevant Logs / Console output

Steps to Reproduce

npx versioned-tests --major -i 2 --all test/versioned/mysql2/transaction.tap.js

You will see the following:

No version match found. Attempting direct install of mysql2@>=1.3.1 <1.6.2

This is because the method for finding the proper version does not take the semver range into consideration as the runner creates a set of packages here. So it falls back to just running

npm install mysql2@'>1.3.1 <1.6.2'

Note: This may be difficult to fix. The investigation should include seeing if it would be ok to use a Map instead of set to keep track of packages for a given suite. An alternate fix could just be to inspect the version by some other means.

Switch to 'main' as default branch

We've settled on main as the new default branch name.

This will involve creating and migrating to the new branch before deleting the prior. We'll also want to ensure we change the base of any existing PR's etc.

Hanselman has some helpful instructions on the blog: https://www.hanselman.com/blog/EasilyRenameYourGitDefaultBranchFromMasterToMain.aspx. I'm sure there are other useful resources out there as well.

  • Change default branch in repo settings
  • Change the base of all open PRs
  • Copy master branch protection rules to main
  • Edit any release documents to reference main instead of master
  • Setup Snyk to use main

Allow modification of test timeout limits through an environment variable

The versioned test runner assumes tests won't take more than a minute by default, after which it sends a SIGTERM event (followed ten seconds later by SIGKILL). Sometimes tests do take longer than a minute, especially in CI situations where the runner may encounter significant resource limitations that extenuate the run considerably. So, we should make this timeout configurable so that users can adjust it as necessary.

Readme Updates

Summary

  • Should conform to new open source template.
    • See the internal repo template project.
  • Clear instructions for development and "building".
  • For Explorer's Hub... perhaps we want to just remove that bit? Not sure we'll need a topic.
  • Update any out of date information

Depending on the amount of content, may want to run by the docs team. They had a bit of consistency and branding changes to the main agent readme.

New template updates

A variety of template updates have recently occurred.

We need to update our relevant content to match.

  • readme
  • contributing
  • issue templates
  • pr template
  • code of conduct

Globbing appears broken for nested folders

Attempting to run latest against the mysql repo which only has tests in nested folders. When I go to run against the latest, no tests run.

versioned-tests --minor --all -i 2 'tests/versioned/**/*.tap.js'

Finding tests in 1 globs
Finding all versions for a package
mysql2(28)
mysql(28)
===============================================================
   mysql
   mysql2
===============================================================
PASS

Log warning when test files exist in folder that are not getting executed

Is your feature request related to a problem? Please describe.

There are times we add new test files but forget to add to the tests stanza within package.json.

Feature Description

Log a very obvious warning or even fail build if test files exists that aren't getting executed.

Priority

Please help us better understand this feature request by choosing a priority from the following options:
[Really Want]

test utils: add node 20

Is your feature request related to a problem? Please describe.

  • Add node 20 to ci, remove 14

Simplify helper agent unloading

Once the next version of (post 11.14.0) newrelic is released we can simplify the following snippet to only use the InstrumentationTracker:

if (
Object.prototype.toString.call(shimmer.registeredInstrumentations) ===
'[object InstrumentationTracker]'
) {
shimmer.registeredInstrumentations = new InstrumentationTracker()
} else {
shimmer.registeredInstrumentations = Object.create(null)
}

Versioned Test Runner Always Runs All Tests

Based on invocation strings in other repositories

// File: package.json
{
    /* ... */
    "versioned": "versioned-tests --minor -i 2 'tests/versioned/*.tap.js'",        
    /* ... */
}

The versioned-tests command appears to accept a path argument, allowing you to decide which test suites will be run.

However, invoking the versioned test runner with a single test suite path still runs all the tests.

If this path (tests/versioned/*.tap.js) is not intended as a "run this and only this test command" then its purpose should be better documented.

Steps to Reproduce

  1. Clone the AWS SDK repository: git clone [email protected]:newrelic/node-newrelic-aws-sdk.git
  2. Install its dependencies: cd node-newrelic-aws-sdk; npm install
  3. Run versioned-tests command: $ npx versioned-tests --minor -i 2 tests/versioned/s3.tap.js

Expected Behavior: versioned-tests runs tests only in tests/versioned/s3.tap.js

Actual Behavior: versioned-tests runs tests in all suites

$ npx versioned-tests --minor -i 2 tests/versioned/s3.tap.js
Finding tests in 1 globs
amazon-dax-client: 3
aws-sdk: 739
===============================================================
 • aws-sdk-tests/dynamodb.tap.js run 3 of 81: running
===============================================================

Remove npm cache clean logic in versioned test runner

Is your feature request related to a problem? Please describe.

We are getting failed versioned test runs and the actual error is getting masked on attempts to clean the npm cache. See this example

2022-05-26T17:12:33.4459591Z stderr
2022-05-26T17:12:33.4460756Z npm WARN deprecated [email protected]: See https://github.com/lydell/source-map-url#deprecated
2022-05-26T17:12:33.4461934Z npm WARN deprecated [email protected]: Please see https://github.com/lydell/urix#deprecated
2022-05-26T17:12:33.4463164Z npm WARN deprecated [email protected]: https://github.com/lydell/resolve-url#deprecated
2022-05-26T17:12:33.4464381Z npm WARN deprecated [email protected]: See https://github.com/lydell/source-map-resolve#deprecated
2022-05-26T17:12:33.4465628Z npm WARN deprecated [email protected]: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
2022-05-26T17:12:33.4467140Z npm WARN deprecated [email protected]: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
2022-05-26T17:12:33.4468559Z npm WARN deprecated [email protected]: support for ECMAScript is superseded by `uglify-js` as of v3.13.0
2022-05-26T17:12:33.4469199Z npm ERR! process terminated
2022-05-26T17:12:33.4469921Z npm ERR! signal SIGTERM
2022-05-26T17:12:33.4470256Z 
2022-05-26T17:12:33.4470908Z npm ERR! A complete log of this run can be found in:
2022-05-26T17:12:33.4471712Z npm ERR!     /home/runner/.npm/_logs/2022-05-26T17_11_19_769Z-debug-0.log
2022-05-26T17:12:33.4472565Z Clearing cache and retrying failed install...
2022-05-26T17:12:33.4473349Z npm ERR! As of npm@5, the npm cache self-heals from corruption issues
2022-05-26T17:12:33.4474304Z npm ERR!   by treating integrity mismatches as cache misses.  As a result,
2022-05-26T17:12:33.4475023Z npm ERR!   data extracted from the cache is guaranteed to be valid.  If you
2022-05-26T17:12:33.4475981Z npm ERR!   want to make sure everything is consistent, use `npm cache verify`
2022-05-26T17:12:33.4476698Z npm ERR!   instead.  Deleting the cache can only make npm go slower, and is
2022-05-26T17:12:33.4477637Z npm ERR!   not likely to correct any problems you may be encountering!
2022-05-26T17:12:33.4478149Z npm ERR! 
2022-05-26T17:12:33.4479135Z npm ERR!   On the other hand, if you're debugging an issue with the installer,
2022-05-26T17:12:33.4479887Z npm ERR!   or race conditions that depend on the timing of writing to an empty
2022-05-26T17:12:33.4481151Z npm ERR!   cache, you can use `npm install --cache /tmp/empty-cache` to use a
2022-05-26T17:12:33.4482433Z npm ERR!   temporary cache instead of nuking the actual one.
2022-05-26T17:12:33.4482753Z npm ERR! 
2022-05-26T17:12:33.4483334Z npm ERR!   If you're sure you want to delete the entire cache, rerun this command
2022-05-26T17:12:33.4483776Z npm ERR!   with --force.
2022-05-26T17:12:33.4483932Z 
2022-05-26T17:12:33.4484185Z npm ERR! A complete log of this run can be found in:
2022-05-26T17:12:33.4484788Z npm ERR!     /home/runner/.npm/_logs/2022-05-26T17_12_32_922Z-debug-0.log
2022-05-26T17:12:33.4485297Z Failed to clear cache: Error: Failed to execute npm cache clean
2022-05-26T17:12:33.4486166Z     at ChildProcess.exitHandler (/home/runner/work/node-newrelic/node-newrelic/node_modules/@newrelic/test-utilities/lib/versioned/runner.js:149:17)
2022-05-26T17:12:33.4486718Z     at ChildProcess.emit (node:events:527:28)
2022-05-26T17:12:33.4487200Z     at Process.ChildProcess._handle.onexit (node:internal/child_process:291:12)
2022-05-26T17:12:33.4487475Z 
2022-05-26T17:12:33.4487697Z ===============================================================

It is very hard to see why this attempt to install a package is failing. Based on the message above they recommend to no longer clean the npm cache.

`getShim` does not return the correct shim instance in agent version 10

Description

v10 of the agent changed a lot around how we instantiate shim to support multiple instrumentations. getShim() has not been updated to account for these changes, so it can return the wrong shim, which will cause any subsequent shim.isWrapped() calls to return false due to ID mismatches. We should update getShim() to work in v10 of the agent.

Workaround

module.exports = function getShim(nodule) {
  const [shimSymbol] = Object.getOwnPropertySymbols(nodule).filter(
    (key) => key.toString() === 'Symbol(shim)'
  )
  return nodule[shimSymbol]
}

Expected Behavior

Using helper.getShim() return the correct shim instance when using v10 of the agent

Steps to Reproduce

  1. Use the Koa unit tests in https://github.com/newrelic/node-newrelic-koa to repro
  2. Replace getShim(object) usage with helper.getShim()
  3. Observe that shim.isWrapped() assertions fail
  4. Add debug statement to isWrapped() function
  5. Launch debugger
  6. Observe that shim id is different from symbol id

Convert CI to GitHub Actions

  • Users can run unit tests at a minimum.

Would aim for all tests functioning for external PR's (forked repos) with these efforts.

Make Third Party Notices updateable via standard CLI tool

https://github.com/newrelic/newrelic-oss-cli#third-party-notice-generation-for-npm-based-projects

-----

Portions copyright Node.js contributors. Depending on your existing libraries and package management settings,
your systems may call externally maintained libraries in addition to those listed above.
See [here](https://nodejs.org/en/docs/meta/topics/dependencies/) and [here](https://github.com/nodejs/node/blob/v4.3.1/LICENSE)
for additional details regarding externally maintained libraries and certain related licenses and notices.”

6.1.0 release broke running folders as an argument

Guessing this is due to the individual file running change but that's just an assumption due to code touched. We changed a few things in here.

The following command will no-longer run any tests: versioned-tests --minor -i 2 "./tests/versioned/apollo-federation"

It just immediately outputs:

Finding tests in 2 globs
Finding all versions for a package
@apollo/federation(32)
@opentelemetry/api(19)
@apollo/gateway(41)
apollo-server(35)
===============================================================
   apollo-federation
===============================================================
PASS

Also not having luck with individual files:

versioned-tests --minor -i 2 "tests/versioned/apollo-federation/transaction-naming.test.js"
Finding tests in 2 globs
No files matched [
  'tests/versioned/apollo-federation/transaction-naming.test.js/package.json',
  'tests/versioned/apollo-federation/transaction-naming.test.js/**/package.json'
]

Use npm 'file's list instead of npmignore

Is your feature request related to a problem? Please describe.

A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Feature Description

A clear and concise description of the feature you want or need.

Describe Alternatives

A clear and concise description of any alternative solutions or features you've considered. Are there examples you could link us to?

Additional context

Add any other context here.

Priority

Please help us better understand this feature request by choosing a priority from the following options:
[Nice to Have, Really Want, Must Have, Blocker]

Minimal code cleanup

We are already in decent shape but do a pass for general things outlined in the Engineering Plan.

rg --pcre2 '(?<!SELECT)(// |^ *\*(?!/))(?! Copyright|.*Apache|.*eslint)'

Add copyright to all source files

Every source file in the repository should contain the copyright block heading on top:

/*
* Copyright 2020 New Relic Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

This includes bash scripts (slightly different commenting style) and code examples. Does not include copy-paste templates.

NOTE: we want the Apache-2.0 license to land first so these are consistent and that license is the current active for the commit(s) applying these changes.


Useful Script

  • Does not update non-JS files.
  • May break when there’s a code directive that needs to be at the top.
  • May need additional modifications for a particular repository.
  • Run git ls-files | grep '\.js$' | grep -Ev '(.eslintrc|^newrelic)' to see list of files
tmp=$(mktemp)   # Create a temporary file
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15

header="/*
 * Copyright 2020 New Relic Corporation. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0
 */
"

for file in $(git ls-files | grep '\.js$' | grep -Ev '(.eslintrc|^newrelic)')
do
    {
    echo -e "$header"
    cat $file
    } > $tmp
    mv $tmp $file
    echo $file
done

rm -f $tmp
trap 0

Default to --all when only Node 16+/npm7 supported in CI (2023?)

We've added the --all to install all deps given newer behaviors in npm7. We don't set this flag for npm6 mostly due to perf reasons. Once our CI no longer runs npm6 / Node versions < 16, we should default this behavior. We may want to still allow the old behavior but probably won't need to.

Update prepare release with conventional commit style

This repo is using the old way of prepping a release that requires updating the auto generated release notes.

Need to update the prep release workflow to use the correct workflow like we do in the node agent repo.

Sample PR

Update Pull Requests settings in Settings > General to squash merges, use PR title and delete head branches

screenshot 2024-03-20 at 9 19 13 AM

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.