diff --git a/.github/workflows/make-agent.yml b/.github/workflows/make-agent.yml index 6508fcaf3..4db0bc9af 100644 --- a/.github/workflows/make-agent.yml +++ b/.github/workflows/make-agent.yml @@ -40,12 +40,6 @@ jobs: path: php-agent repository: ${{ inputs.origin }}/newrelic-php-agent ref: ${{ inputs.ref }} - - name: Enable arm64 emulation - if: ${{ inputs.arch == 'arm64' }} - uses: docker/setup-qemu-action@v3 - with: - image: tonistiigi/binfmt:${{vars.BINFMT_IMAGE_VERSION}} - platforms: arm64 - name: Login to Docker Hub uses: docker/login-action@v3 with: diff --git a/.github/workflows/make-integration-tests.yml b/.github/workflows/make-integration-tests.yml index 0b6660575..0d5662076 100644 --- a/.github/workflows/make-integration-tests.yml +++ b/.github/workflows/make-integration-tests.yml @@ -24,6 +24,10 @@ on: description: 'runner type' required: true type: string + use-valgrind: + required: true + default: false + type: boolean jobs: test-agent: @@ -56,12 +60,6 @@ jobs: run: | chmod 755 php-agent/bin/integration_runner chmod 755 php-agent/agent/modules/newrelic.so - - name: Enable arm64 emulation - if: ${{ inputs.arch == 'arm64' }} - uses: docker/setup-qemu-action@v3 - with: - image: tonistiigi/binfmt:${{vars.BINFMT_IMAGE_VERSION}} - platforms: arm64 - name: Login to Docker Hub uses: docker/login-action@v3 with: @@ -83,7 +81,7 @@ jobs: run: | docker exec \ -e PHPS=${{matrix.php}} \ - -e INTEGRATION_ARGS="-license ${{secrets.NR_TEST_LICENSE}} -collector ${{secrets.NR_COLLECTOR_HOST}} -agent agent/modules/newrelic.so" \ + -e INTEGRATION_ARGS="-license ${{secrets.NR_TEST_LICENSE}} -collector ${{secrets.NR_COLLECTOR_HOST}} -agent agent/modules/newrelic.so ${{ inputs.use-valgrind && '-valgrind /usr/bin/valgrind' }}" \ -e APP_supportability=${{secrets.APP_SUPPORTABILITY}} \ -e ACCOUNT_supportability=${{secrets.ACCOUNT_SUPPORTABILITY}} \ -e ACCOUNT_supportability_trusted=${{secrets.ACCOUNT_SUPPORTABILITY_TRUSTED}} \ diff --git a/.github/workflows/run-integration-tests.yml b/.github/workflows/run-integration-tests.yml index 1274d2683..ef847f564 100644 --- a/.github/workflows/run-integration-tests.yml +++ b/.github/workflows/run-integration-tests.yml @@ -21,15 +21,16 @@ on: runner-type: description: 'Type of a runner to use for integration tests on arm64' required: true - default: 'ubuntu-20.04-4core' + default: 'ubuntu-24.04-arm' type: choice options: - - ubuntu-20.04-4core - - ubuntu-20.04-8core - - ubuntu-20.04-16core - - ubuntu-22.04-4core - - ubuntu-latest - + - ubuntu-22.04-arm + - ubuntu-24.04-arm + use-valgrind: + description: 'Use valgrind?' + required: true + default: false + type: boolean jobs: build-test-runner-amd64: uses: ./.github/workflows/make-for-platform-on-arch.yml @@ -55,7 +56,7 @@ jobs: artifact-name: integration_runner artifact-pattern: bin/integration_runner arch: arm64 - runs-on: ubuntu-latest + runs-on: ${{inputs.runner-type}} secrets: inherit build-agent-amd64: @@ -72,7 +73,7 @@ jobs: origin: ${{ inputs.origin }} ref: ${{ inputs.ref }} arch: arm64 - runs-on: ubuntu-latest + runs-on: ${{inputs.runner-type}} secrets: inherit test-amd64: @@ -81,6 +82,7 @@ jobs: with: origin: ${{ inputs.origin }} ref: ${{ inputs.ref }} + use-valgrind: ${{ inputs.use-valgrind }} arch: amd64 runs-on: ubuntu-latest continue-on-error: false @@ -91,6 +93,7 @@ jobs: with: origin: ${{ inputs.origin }} ref: ${{ inputs.ref }} + use-valgrind: ${{ inputs.use-valgrind }} arch: arm64 runs-on: ${{inputs.runner-type}} continue-on-error: true diff --git a/.github/workflows/test-agent.yml b/.github/workflows/test-agent.yml index efb68d872..afb7252f0 100644 --- a/.github/workflows/test-agent.yml +++ b/.github/workflows/test-agent.yml @@ -77,7 +77,8 @@ jobs: - name: Run go vet run: go vet -C ./php-agent/daemon ./... shell: bash - daemon-unit-tests: + + daemon-unit-tests-amd64: runs-on: ubuntu-latest env: IMAGE_NAME: newrelic/nr-php-agent-builder @@ -86,18 +87,50 @@ jobs: strategy: matrix: platform: [gnu, musl] - arch: [amd64, arm64] + arch: [amd64] steps: - name: Checkout newrelic-php-agent code uses: actions/checkout@v4 with: path: php-agent - - name: Enable arm64 emulation - if: ${{ matrix.arch == 'arm64' }} - uses: docker/setup-qemu-action@v3 + - name: Login to Docker Hub + uses: docker/login-action@v3 with: - image: tonistiigi/binfmt:${{vars.BINFMT_IMAGE_VERSION}} - platforms: arm64 + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build daemon + run: > + docker run --rm --platform linux/${{matrix.arch}} + -v "${GITHUB_WORKSPACE}/php-agent":"/usr/local/src/newrelic-php-agent" + -e ACCOUNT_supportability=${{secrets.ACCOUNT_SUPPORTABILITY}} + -e APP_supportability=${{secrets.APP_SUPPORTABILITY}} + $IMAGE_NAME:$IMAGE_TAG-${{ matrix.platform }}-$IMAGE_VERSION daemon + - name: Run daemon tests + run: > + docker run --rm --platform linux/${{matrix.arch}} + -v "${GITHUB_WORKSPACE}/php-agent":"/usr/local/src/newrelic-php-agent" + $IMAGE_NAME:$IMAGE_TAG-${{ matrix.platform }}-$IMAGE_VERSION daemon_test + - name: Save integration_runner for integration tests + uses: actions/upload-artifact@v4 + with: + name: integration_runner-${{matrix.platform}}-${{matrix.arch}} + path: php-agent/bin/integration_runner + + daemon-unit-tests-arm64: + runs-on: ubuntu-24.04-arm + env: + IMAGE_NAME: newrelic/nr-php-agent-builder + IMAGE_TAG: make-go + IMAGE_VERSION: ${{vars.MAKE_GO_VERSION}} + strategy: + matrix: + platform: [gnu, musl] + arch: [arm64] + steps: + - name: Checkout newrelic-php-agent code + uses: actions/checkout@v4 + with: + path: php-agent - name: Login to Docker Hub uses: docker/login-action@v3 with: @@ -120,7 +153,8 @@ jobs: with: name: integration_runner-${{matrix.platform}}-${{matrix.arch}} path: php-agent/bin/integration_runner - agent-unit-test: + + agent-unit-test-amd64: runs-on: ubuntu-latest env: IMAGE_NAME: newrelic/nr-php-agent-builder @@ -129,15 +163,8 @@ jobs: strategy: matrix: platform: [gnu, musl] - arch: [amd64, arm64] + arch: [amd64] php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] - exclude: - - arch: arm64 - php: '7.2' - - arch: arm64 - php: '7.3' - - arch: arm64 - php: '7.4' include: - codecov: 0 - platform: gnu @@ -148,12 +175,6 @@ jobs: uses: actions/checkout@v4 with: path: php-agent - - name: Enable arm64 emulation - if: ${{ matrix.arch == 'arm64' }} - uses: docker/setup-qemu-action@v3 - with: - image: tonistiigi/binfmt:${{vars.BINFMT_IMAGE_VERSION}} - platforms: arm64 - name: Login to Docker Hub uses: docker/login-action@v3 with: @@ -162,18 +183,12 @@ jobs: - name: Determine if valgrind can be used id: get-check-variant run: | - if [[ ${{ matrix.platform }} = 'gnu' && ${{matrix.arch}} = 'amd64' ]]; then + if [[ ${{ matrix.platform }} = 'gnu' ]]; then echo "AXIOM_CHECK_VARIANT=valgrind" >> $GITHUB_OUTPUT else echo "AXIOM_CHECK_VARIANT=check" >> $GITHUB_OUTPUT fi - if [[ ${{matrix.arch}} = 'arm64' ]]; then - echo "AGENT_CHECK_VARIANT=check" >> $GITHUB_OUTPUT - elif [[ ${{ matrix.platform }} = 'gnu' ]]; then - echo "AGENT_CHECK_VARIANT=valgrind" >> $GITHUB_OUTPUT - else - echo "AGENT_CHECK_VARIANT=valgrind" >> $GITHUB_OUTPUT - fi + echo "AGENT_CHECK_VARIANT=valgrind" >> $GITHUB_OUTPUT - name: Build axiom run: > docker run --rm --platform linux/${{matrix.arch}} @@ -228,22 +243,86 @@ jobs: name: agent.gcov-${{matrix.platform}}-${{matrix.arch}}-${{matrix.php}} include-hidden-files: true path: php-agent/agent/.libs/*.gc* - integration-tests: - needs: [daemon-unit-tests, agent-unit-test] + + agent-unit-test-arm64: + runs-on: ubuntu-24.04-arm + env: + IMAGE_NAME: newrelic/nr-php-agent-builder + IMAGE_TAG: make-php + IMAGE_VERSION: ${{vars.MAKE_PHP_VERSION}} + strategy: + matrix: + platform: [gnu, musl] + arch: [arm64] + php: ['8.0', '8.1', '8.2', '8.3', '8.4'] + include: + - codecov: 0 + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + with: + path: php-agent + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Determine if valgrind can be used + id: get-check-variant + run: | + echo "AXIOM_CHECK_VARIANT=check" >> $GITHUB_OUTPUT + echo "AGENT_CHECK_VARIANT=check" >> $GITHUB_OUTPUT + - name: Build axiom + run: > + docker run --rm --platform linux/${{matrix.arch}} + -v "${GITHUB_WORKSPACE}/php-agent":"/usr/local/src/newrelic-php-agent" + -e ENABLE_COVERAGE=${{matrix.codecov}} + $IMAGE_NAME:$IMAGE_TAG-${{matrix.php}}-${{matrix.platform}}-$IMAGE_VERSION make axiom + - name: Build agent + run: > + docker run --rm --platform linux/${{matrix.arch}} + -v "${GITHUB_WORKSPACE}/php-agent":"/usr/local/src/newrelic-php-agent" + -e ENABLE_COVERAGE=${{matrix.codecov}} + $IMAGE_NAME:$IMAGE_TAG-${{matrix.php}}-${{matrix.platform}}-$IMAGE_VERSION make agent + - name: Build axiom unit tests + run: > + docker run --rm --platform linux/${{matrix.arch}} + -v "${GITHUB_WORKSPACE}/php-agent":"/usr/local/src/newrelic-php-agent" + -e ENABLE_COVERAGE=${{matrix.codecov}} + $IMAGE_NAME:$IMAGE_TAG-${{matrix.php}}-${{matrix.platform}}-$IMAGE_VERSION make axiom-tests + - name: Run axiom unit tests + run: > + docker run --rm --platform linux/${{matrix.arch}} + -v "${GITHUB_WORKSPACE}/php-agent":"/usr/local/src/newrelic-php-agent" + -e ENABLE_COVERAGE=${{matrix.codecov}} + $IMAGE_NAME:$IMAGE_TAG-${{matrix.php}}-${{matrix.platform}}-$IMAGE_VERSION make axiom-${{ steps.get-check-variant.outputs.AXIOM_CHECK_VARIANT }} + - name: Build agent unit tests + run: > + docker run --rm --platform linux/${{matrix.arch}} + -v "${GITHUB_WORKSPACE}/php-agent":"/usr/local/src/newrelic-php-agent" + -e ENABLE_COVERAGE=${{matrix.codecov}} + $IMAGE_NAME:$IMAGE_TAG-${{matrix.php}}-${{matrix.platform}}-$IMAGE_VERSION make agent-tests + - name: Run agent unit tests + run: > + docker run --rm --platform linux/${{matrix.arch}} + -v "${GITHUB_WORKSPACE}/php-agent":"/usr/local/src/newrelic-php-agent" + -e ENABLE_COVERAGE=${{matrix.codecov}} + $IMAGE_NAME:$IMAGE_TAG-${{matrix.php}}-${{matrix.platform}}-$IMAGE_VERSION make agent-${{ steps.get-check-variant.outputs.AGENT_CHECK_VARIANT }} + - name: Save newrelic.so for integration tests + uses: actions/upload-artifact@v4 + with: + name: newrelic.so-${{matrix.platform}}-${{matrix.arch}}-${{matrix.php}} + path: php-agent/agent/modules/newrelic.so + + integration-tests-amd64: + needs: [daemon-unit-tests-amd64, agent-unit-test-amd64] runs-on: ubuntu-latest strategy: fail-fast: false matrix: platform: [gnu, musl] - arch: [amd64, arm64] + arch: [amd64] php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] - exclude: - - arch: arm64 - php: '7.2' - - arch: arm64 - php: '7.3' - - arch: arm64 - php: '7.4' include: - codecov: 0 - platform: gnu @@ -280,12 +359,6 @@ jobs: run: | chmod 755 php-agent/bin/integration_runner chmod 755 php-agent/agent/modules/newrelic.so - - name: Enable arm64 emulation - if: ${{ matrix.arch == 'arm64' }} - uses: docker/setup-qemu-action@v3 - with: - image: tonistiigi/binfmt:${{vars.BINFMT_IMAGE_VERSION}} - platforms: arm64 - name: Login to Docker Hub uses: docker/login-action@v3 with: @@ -323,7 +396,6 @@ jobs: -e LICENSE_lasp_suite_random_3=${{secrets.LICENSE_LASP_SUITE_RANDOM_3}} \ nr-php make lasp-test-all - name: Run integration tests - if: ${{ matrix.arch == 'amd64' }} working-directory: ./php-agent shell: bash run: | @@ -358,3 +430,93 @@ jobs: working-directory: ./php-agent run: | make test-services-stop + + integration-tests-arm64: + needs: [daemon-unit-tests-arm64, agent-unit-test-arm64] + runs-on: ubuntu-24.04-arm + strategy: + fail-fast: false + matrix: + platform: [gnu, musl] + arch: [arm64] + php: ['8.0', '8.1', '8.2', '8.3', '8.4'] + steps: + - name: Checkout integration tests + uses: actions/checkout@v4 + with: + path: php-agent + - name: Get integration_runner + uses: actions/download-artifact@v4 + with: + name: integration_runner-${{matrix.platform}}-${{matrix.arch}} + path: php-agent/bin + - name: Get newrelic.so + uses: actions/download-artifact@v4 + with: + name: newrelic.so-${{matrix.platform}}-${{matrix.arch}}-${{matrix.php}} + path: php-agent/agent/modules + - name: Prep artifacts for use + run: | + chmod 755 php-agent/bin/integration_runner + chmod 755 php-agent/agent/modules/newrelic.so + - name: Emable amd64 emulation + uses: docker/setup-qemu-action@v3 + with: + image: tonistiigi/binfmt:${{vars.BINFMT_IMAGE_VERSION}} + platforms: amd64 + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Start services + env: + PHP: ${{matrix.php}} + LIBC: ${{matrix.platform}} + PLATFORM: linux/${{matrix.arch}} + AGENT_CODE: ${{github.workspace}}/php-agent + IMAGE_VERSION: ${{vars.MAKE_PHP_VERSION}} + working-directory: ./php-agent + run: | + make test-services-start + - name: Test events limits + working-directory: ./php-agent + shell: bash + run: | + docker exec \ + -e PHPS=${{matrix.php}} \ + -e INTEGRATION_ARGS="-license ${{secrets.NR_TEST_LICENSE}} -collector ${{secrets.NR_COLLECTOR_HOST}} -agent agent/modules/newrelic.so" \ + nr-php make integration-events-limits + - name: Test LASP + working-directory: ./php-agent + shell: bash + run: | + docker exec \ + -e PHPS=${{matrix.php}} \ + -e INTEGRATION_ARGS="-license ${{secrets.NR_TEST_LICENSE}} -collector ${{secrets.NR_COLLECTOR_HOST}} -agent agent/modules/newrelic.so" \ + -e LICENSE_lasp_suite_most_secure=${{secrets.LICENSE_LASP_SUITE_MOST_SECURE}} \ + -e LICENSE_lasp_suite_least_secure=${{secrets.LICENSE_LASP_SUITE_LEAST_SECURE}} \ + -e LICENSE_lasp_suite_random_1=${{secrets.LICENSE_LASP_SUITE_RANDOM_1}} \ + -e LICENSE_lasp_suite_random_2=${{secrets.LICENSE_LASP_SUITE_RANDOM_2}} \ + -e LICENSE_lasp_suite_random_3=${{secrets.LICENSE_LASP_SUITE_RANDOM_3}} \ + nr-php make lasp-test-all + - name: Run integration tests + working-directory: ./php-agent + shell: bash + run: | + docker exec \ + -e PHPS=${{matrix.php}} \ + -e INTEGRATION_ARGS="-license ${{secrets.NR_TEST_LICENSE}} -collector ${{secrets.NR_COLLECTOR_HOST}} -agent agent/modules/newrelic.so" \ + -e APP_supportability=${{secrets.APP_SUPPORTABILITY}} \ + -e ACCOUNT_supportability=${{secrets.ACCOUNT_SUPPORTABILITY}} \ + -e ACCOUNT_supportability_trusted=${{secrets.ACCOUNT_SUPPORTABILITY_TRUSTED}} \ + -e SYNTHETICS_HEADER_supportability=${{secrets.SYNTHETICS_HEADER_SUPPORTABILITY}} \ + nr-php make integration-tests + - name: Stop services + env: + PHP: ${{matrix.php}} + LIBC: ${{matrix.platform}} + AGENT_CODE: ${{github.workspace}}/php-agent + working-directory: ./php-agent + run: | + make test-services-stop diff --git a/VERSION b/VERSION index ba9aff72c..933dbb1df 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -11.9.0 +11.10.0 diff --git a/agent/lib_composer.c b/agent/lib_composer.c index f6596639a..674bff3c3 100644 --- a/agent/lib_composer.c +++ b/agent/lib_composer.c @@ -7,6 +7,7 @@ #include "fw_hooks.h" #include "fw_support.h" #include "nr_txn.h" +#include "php_globals.h" #include "util_logging.h" #include "util_memory.h" #include "util_syscalls.h" @@ -136,6 +137,13 @@ static void nr_execute_handle_autoload_composer_get_packages_information( __func__); return; } + + if (NR_PHP_PROCESS_GLOBALS(composer_api_per_process_detection)) { + // set the per-process flag to true to avoid re-running composer api + // detection when the per-process detection is enabled. + NR_PHP_PROCESS_GLOBALS(composer_packages_detected) = 1; + } + if (IS_ARRAY == Z_TYPE(retval)) { zend_string* package_name = NULL; zval* package_version = NULL; diff --git a/agent/php_execute.c b/agent/php_execute.c index df3d86c71..7257f7471 100644 --- a/agent/php_execute.c +++ b/agent/php_execute.c @@ -891,11 +891,26 @@ static void nr_execute_handle_autoload(const char* filename, return; } + /* + * There is a possibility of the txn being NULL if nr_php_end_txn has been called. + * Verify txn is not null before dereferencing and continuing on. + */ + if (NULL == NRPRG(txn)) { + return; + } + if (NRPRG(txn)->composer_info.autoload_detected) { // autoload already handled return; } + if (NR_PHP_PROCESS_GLOBALS(composer_api_per_process_detection) + && NR_PHP_PROCESS_GLOBALS(composer_packages_detected)) { + // do nothing if per-process detection is enabled and the flag to track + // detection is true + return; + } + if (!nr_striendswith(STR_AND_LEN(filename), AUTOLOAD_MAGIC_FILE, AUTOLOAD_MAGIC_FILE_LEN)) { // not an autoload file diff --git a/agent/php_globals.h b/agent/php_globals.h index ff9a9824f..4d0a2fe24 100644 --- a/agent/php_globals.h +++ b/agent/php_globals.h @@ -75,6 +75,12 @@ typedef struct _nrphpglobals_t { int apache_threaded; /* 1 if a threaded MPM is in use, 0 otherwise */ int preload_framework_library_detection; /* Enables preloading framework and library detection */ + int composer_api_per_process_detection; /* Enables per-process VM package + detection when Composer API is also + enabled */ + int composer_packages_detected; /* Flag to indicate that Composer package + detection has run. Used in conjunction with + composer_api_per_process_detection. */ char* docker_id; /* 64 byte hex docker ID parsed from /proc/self/mountinfo */ /* Original PHP callback pointer contents */ diff --git a/agent/php_minit.c b/agent/php_minit.c index 08f5a02c5..7cd14bc59 100644 --- a/agent/php_minit.c +++ b/agent/php_minit.c @@ -456,6 +456,7 @@ PHP_MINIT_FUNCTION(newrelic) { = nr_php_check_for_upgrade_license_key(); NR_PHP_PROCESS_GLOBALS(high_security) = 0; NR_PHP_PROCESS_GLOBALS(preload_framework_library_detection) = 1; + NR_PHP_PROCESS_GLOBALS(composer_packages_detected) = 0; nr_php_populate_apache_process_globals(); nr_php_api_distributed_trace_register_userland_class(TSRMLS_C); /* diff --git a/agent/php_nrini.c b/agent/php_nrini.c index dce25a27a..6cddef5b2 100644 --- a/agent/php_nrini.c +++ b/agent/php_nrini.c @@ -537,6 +537,33 @@ static PHP_INI_MH(nr_preload_framework_library_detection_mh) { return SUCCESS; } +static PHP_INI_MH(nr_composer_per_process_detection_mh) { + int val; + + (void)entry; + (void)NEW_VALUE_LEN; + (void)mh_arg1; + (void)mh_arg2; + (void)mh_arg3; + (void)stage; + NR_UNUSED_TSRMLS; + + val = nr_bool_from_str(NEW_VALUE); + + if (-1 == val) { + nrl_warning(NRL_INIT, + "The value \"%s\" is not valid for the " + "newrelic.vulnerability_management.composer_api.per_process_" + "detection setting, using default value instead.", + NEW_VALUE); + return FAILURE; + } + + NR_PHP_PROCESS_GLOBALS(composer_api_per_process_detection) = val ? 1 : 0; + + return SUCCESS; +} + static PHP_INI_MH(nr_loglevel_mh) { nr_status_t rv; @@ -2055,6 +2082,17 @@ PHP_INI_ENTRY_EX("newrelic.preload_framework_library_detection", nr_preload_framework_library_detection_mh, 0) +/* + * Enables per-process Composer API package detection and reporting. Depends on + * newrelic.vulnerability_management.composer_api.enabled. + */ +PHP_INI_ENTRY_EX( + "newrelic.vulnerability_management.composer_api.per_process_detection", + "1", + NR_PHP_SYSTEM, + nr_composer_per_process_detection_mh, + 0) + /* * Daemon */ @@ -3135,7 +3173,7 @@ STD_PHP_INI_ENTRY_EX("newrelic.vulnerability_management.package_detection.enable nr_enabled_disabled_dh) STD_PHP_INI_ENTRY_EX("newrelic.vulnerability_management.composer_api.enabled", - "0", + "1", NR_PHP_REQUEST, nr_boolean_mh, vulnerability_management_composer_api_enabled, diff --git a/agent/scripts/newrelic.ini.template b/agent/scripts/newrelic.ini.template index aeaf75641..cecc1486c 100644 --- a/agent/scripts/newrelic.ini.template +++ b/agent/scripts/newrelic.ini.template @@ -1363,11 +1363,21 @@ newrelic.daemon.logfile = "/var/log/newrelic/newrelic-daemon.log" ; Setting: newrelic.vulnerability_management.composer_api.enabled ; Type : boolean ; Scope : per-directory -; Default: false +; Default: true ; Info : Toggles whether the agent should try using Composer's runtime API ; to gather package information for vulnerability management. ; -;newrelic.vulnerability_management.composer_api.enabled = false +;newrelic.vulnerability_management.composer_api.enabled = true + +; Setting: newrelic.vulnerability_management.composer_api.per_process_detection +; Type : boolean +; Scope : system +; Default: true +; Info : Controls the frequency at which Composer API samples the runtime environment +; for package data. When set to `true`, sampling will only occur once per process. +; If false, Composer will sample the environment every request, increasing the frequency which this package detection is performed. +; +;newrelic.vulnerability_management.composer_api.per_process_detection = true ; Setting: newrelic.message_tracer.segment_parameters.enabled ; Type : boolean diff --git a/axiom/nr_version.c b/axiom/nr_version.c index 902f25ba4..098fd0650 100644 --- a/axiom/nr_version.c +++ b/axiom/nr_version.c @@ -23,7 +23,6 @@ /* * Current version naming scheme is gemstones * - * hydrangea 18Jan2023 (10.5) * impatiens 13Feb2023 (10.6) * jasmine 08Mar2023 (10.7) * kalmia 27Mar2023 (10.8) @@ -50,8 +49,9 @@ * fluorite 18Feb2025 (11.6) * gaspeite 19Mar2025 (11.7) * hiddenite 21Apr2025 (11.8) + * indicolite 13May2025 (11.9) */ -#define NR_CODENAME "indicolite" +#define NR_CODENAME "jade" const char* nr_version(void) { return NR_STR2(NR_VERSION); diff --git a/daemon/cmd/integration_runner/main.go b/daemon/cmd/integration_runner/main.go index f1a65a402..60c0247d8 100644 --- a/daemon/cmd/integration_runner/main.go +++ b/daemon/cmd/integration_runner/main.go @@ -344,6 +344,10 @@ func main() { ctx = integration.NewContext(*flagPHP, *flagCGI) ctx.Valgrind = *flagValgrind + if ctx.Valgrind != "" && *flagWorkers != 1 { + fmt.Fprintf(os.Stderr, "cannot run valgrind on multiple workers\n") + os.Exit(1) + } ctx.Timeout = *flagTimeout // Settings common to all tests. diff --git a/daemon/go.mod b/daemon/go.mod index 01a06cd6b..a913dbd87 100644 --- a/daemon/go.mod +++ b/daemon/go.mod @@ -1,7 +1,7 @@ module github.com/newrelic/newrelic-php-agent/daemon go 1.24.0 -toolchain go1.24.2 +toolchain go1.24.4 require ( github.com/golang/protobuf v1.5.3 diff --git a/daemon/internal/newrelic/integration/transaction.go b/daemon/internal/newrelic/integration/transaction.go index be2819aa7..b69b4b004 100644 --- a/daemon/internal/newrelic/integration/transaction.go +++ b/daemon/internal/newrelic/integration/transaction.go @@ -48,7 +48,7 @@ func PhpTx(src Script, env, settings map[string]string, ctx *Context) (Tx, error args := phpArgs(nil, filepath.Base(src.Name()), false, settings) - if ctx.Valgrind != "" { + if ctx.Valgrind != "" && settings["newrelic.appname"] != "skipif" { txn = &ValgrindCLI{ CLI: CLI{ Path: ctx.PHP, @@ -81,6 +81,7 @@ func PhpTx(src Script, env, settings map[string]string, ctx *Context) (Tx, error // See: https://tools.ietf.org/html/rfc3875 func CgiTx(src Script, env, settings map[string]string, headers http.Header, ctx *Context) (Tx, error) { var err error + var txn Tx req := &http.Request{ Method: env["REQUEST_METHOD"], @@ -105,34 +106,69 @@ func CgiTx(src Script, env, settings map[string]string, headers http.Header, ctx return nil, fmt.Errorf("unable to create cgi request: %v", err) } - tx := &CGI{ - request: req, - handler: &cgi.Handler{ - Path: ctx.CGI, - Dir: src.Dir(), - Args: phpArgs(nil, "", false, settings), - }, - } + if ctx.Valgrind != "" { + tx := &ValgrindCGI{ + CGI: CGI{ + request: req, + handler: &cgi.Handler{ + Path: ctx.CGI, + Dir: src.Dir(), + Args: phpArgs(nil, "", false, settings), + }, + }, + Valgrind: ctx.Valgrind, + Timeout: ctx.Timeout, + } + tx.handler.Env = append(tx.handler.Env, + "SCRIPT_FILENAME="+scriptFile, + "SCRIPT_NAME=/"+filepath.Base(src.Name()), + "REDIRECT_STATUS=200") + tx.handler.Env = append(tx.handler.Env, flatten(env)...) + + // If the environment includes a REQUEST_URI and doesn't include an explicit + // PATH_INFO, we'll set it here to avoid problems with Go's CGI package + // attempting to guess what the PATH_INFO should be. + if ruri, ok := env["REQUEST_URI"]; ok { + if _, ok := env["PATH_INFO"]; !ok { + tx.handler.Env = append(tx.handler.Env, "PATH_INFO="+ruri) + } + } - tx.handler.Env = append(tx.handler.Env, - "SCRIPT_FILENAME="+scriptFile, - "SCRIPT_NAME=/"+filepath.Base(src.Name()), - "REDIRECT_STATUS=200") - tx.handler.Env = append(tx.handler.Env, flatten(env)...) - - // If the environment includes a REQUEST_URI and doesn't include an explicit - // PATH_INFO, we'll set it here to avoid problems with Go's CGI package - // attempting to guess what the PATH_INFO should be. - if ruri, ok := env["REQUEST_URI"]; ok { - if _, ok := env["PATH_INFO"]; !ok { - tx.handler.Env = append(tx.handler.Env, "PATH_INFO="+ruri) + if !src.IsFile() { + return withTempFile(tx, src.Name(), src.Bytes()), nil + } + txn = tx + } else { + tx := &CGI{ + request: req, + handler: &cgi.Handler{ + Path: ctx.CGI, + Dir: src.Dir(), + Args: phpArgs(nil, "", false, settings), + }, + } + tx.handler.Env = append(tx.handler.Env, + "SCRIPT_FILENAME="+scriptFile, + "SCRIPT_NAME=/"+filepath.Base(src.Name()), + "REDIRECT_STATUS=200") + tx.handler.Env = append(tx.handler.Env, flatten(env)...) + + // If the environment includes a REQUEST_URI and doesn't include an explicit + // PATH_INFO, we'll set it here to avoid problems with Go's CGI package + // attempting to guess what the PATH_INFO should be. + if ruri, ok := env["REQUEST_URI"]; ok { + if _, ok := env["PATH_INFO"]; !ok { + tx.handler.Env = append(tx.handler.Env, "PATH_INFO="+ruri) + } } - } - if !src.IsFile() { - return withTempFile(tx, src.Name(), src.Bytes()), nil + if !src.IsFile() { + return withTempFile(tx, src.Name(), src.Bytes()), nil + } + txn = tx } - return tx, nil + + return txn, nil } // phpArgs builds the command line for a PHP process. diff --git a/daemon/internal/newrelic/integration/valgrind.go b/daemon/internal/newrelic/integration/valgrind.go index 6ced42d31..b1ef069d1 100644 --- a/daemon/internal/newrelic/integration/valgrind.go +++ b/daemon/internal/newrelic/integration/valgrind.go @@ -10,6 +10,7 @@ import ( "fmt" "io/ioutil" "net/http" + "net/http/httptest" "sync" "time" @@ -24,6 +25,12 @@ type ValgrindCLI struct { Timeout time.Duration } +type ValgrindCGI struct { + CGI + Valgrind string + Timeout time.Duration +} + func (tx *ValgrindCLI) Execute() (http.Header, []byte, error) { if len(tx.Path) == 0 { return nil, []byte("skip: executable not specified"), nil @@ -34,8 +41,13 @@ func (tx *ValgrindCLI) Execute() (http.Header, []byte, error) { // valgrind reports to their tests in the same way we use the appname // to link the transaction data. Failing that, perhaps we could use // the valgrind process's pid instead. - valgrindMu.Lock() - defer valgrindMu.Unlock() + // + // We prevent concurrent invocations by disallowing valgrind when + // the threads argument is greater than 1. Previously, we used the + // commented out locks below. This was changed to allow subprocesses + // (i.e. curl) to run without deadlocking. + //valgrindMu.Lock() + //defer valgrindMu.Unlock() cmd := valgrind.Memcheck(tx.Valgrind, "--quiet") cmd.Args = append(cmd.Args, "--xml=yes") @@ -105,6 +117,87 @@ func (tx *ValgrindCLI) Execute() (http.Header, []byte, error) { return nil, output, err } +func (tx *ValgrindCGI) Execute() (http.Header, []byte, error) { + if len(tx.handler.Path) == 0 { + return nil, []byte("skip: executable not specified"), nil + } + + // For now, we don't have a mechanism to handle concurrent invocations + // of Valgrind. In the future, we could use the appname to connect + // valgrind reports to their tests in the same way we use the appname + // to link the transaction data. Failing that, perhaps we could use + // the valgrind process's pid instead. + // + // We prevent concurrent invocations by disallowing valgrind when + // the threads argument is greater than 1. Previously, we used the + // commented out locks below. This was changed to allow subprocesses + // (i.e. curl) to run without deadlocking. + //valgrindMu.Lock() + //defer valgrindMu.Unlock() + + cmd := valgrind.Memcheck(tx.Valgrind, "--quiet") + cmd.Args = append(cmd.Args, "--xml=yes") + cmd.Args = append(cmd.Args, "--xml-socket="+valgrindLn.Addr().String()) + cmd.Args = append(cmd.Args, "--") + cmd.Args = append(cmd.Args, tx.handler.Path) + if len(tx.handler.Args) > 0 { + cmd.Args = append(cmd.Args, tx.handler.Args...) + } + + log.Debugf("command: %v", cmd) + + // Replace the handler with valgrind + tx.handler.Path = cmd.Path + // The first Arg is the Path. + // ServeHTTP will re-add Path + // to the front of Args + tx.handler.Args = cmd.Args[1:] + + ch := make(chan resultOrError, 1) + go func() { + var result resultOrError + result.R, result.E = acceptOneReport(tx.Timeout) + ch <- result + }() + + resp := httptest.NewRecorder() + tx.handler.ServeHTTP(resp, tx.request) + + vgOutput := <-ch + + // Append the output from Valgrind to the test output. + // + // TODO: Eventually we want to report valgrind output separately, so we can + // treat valgrind errors similarly to failed test expectations. i.e. We'd + // like to add them to Test.Failures. After all, each test has an implicit + // expectation that it will not exhibit memory bugs! + // + // TODO: Once the former is in place, we should be able to parse the memory + // leak reports produced by the Zend Memory Manager from the test output and + // report them the same way as valgrind errors. + output := resp.Body.Bytes() + if vgOutput.R != nil && len(vgOutput.R.Errors) > 0 { + // Safe to ignore the error here, Report.MarshalText() never fails. + data, _ := vgOutput.R.MarshalText() + output = append(output, '\n') + output = append(output, data...) + } + + // Ensure a non-nil error is returned when valgrind detects errors. + // Otherwise, the test could be marked as passing if it does not have + // any expectations on the test output. This sucks. + // + // TODO: Remove this when valgrind errors can be treated as failed test + // expectations. + err := vgOutput.E + if err == nil && vgOutput.R != nil && len(vgOutput.R.Errors) > 0 { + err = fmt.Errorf("detected %d memory errors", len(vgOutput.R.Errors)) + } + + return resp.HeaderMap, output, err + +} + // resultOrError is a poor man's sum type. type resultOrError struct { R *valgrind.Report diff --git a/tests/integration/autoloader/test_autoloader_with_composer_disabled.php b/tests/integration/autoloader/test_autoloader_with_composer_disabled.php index f564c0a63..e995d21de 100644 --- a/tests/integration/autoloader/test_autoloader_with_composer_disabled.php +++ b/tests/integration/autoloader/test_autoloader_with_composer_disabled.php @@ -12,6 +12,7 @@ */ /*INI +newrelic.vulnerability_management.composer_api.enabled = false */ /*EXPECT_PHP_PACKAGES null*/ diff --git a/tests/integration/autoloader/test_autoloader_without_composer_disabled.php b/tests/integration/autoloader/test_autoloader_without_composer_disabled.php index 8e527a220..31b210fee 100644 --- a/tests/integration/autoloader/test_autoloader_without_composer_disabled.php +++ b/tests/integration/autoloader/test_autoloader_without_composer_disabled.php @@ -11,6 +11,7 @@ */ /*INI +newrelic.vulnerability_management.composer_api.enabled = false */ /*EXPECT_METRICS_DONT_EXIST diff --git a/tests/integration/external/guzzle5/test_cat.php b/tests/integration/external/guzzle5/test_cat.php index 9e01532df..254bc23f3 100644 --- a/tests/integration/external/guzzle5/test_cat.php +++ b/tests/integration/external/guzzle5/test_cat.php @@ -52,6 +52,7 @@ [{"name":"OtherTransactionTotalTime"}, [1, "??", "??", "??", "??", "??"]], [{"name":"OtherTransactionTotalTime/php__FILE__"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/library/Guzzle 4-5/detected"}, [1, 0, 0, 0, 0, 0]], + [{"name":"Supportability/library/Autoloader/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Unsupported/curl_setopt/CURLOPT_HEADERFUNCTION/closure"}, [3, 0, 0, 0, 0, 0]], [{"name":"Supportability/Logging/Forwarding/PHP/enabled"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Logging/Metrics/PHP/enabled"}, [1, "??", "??", "??", "??", "??"]], diff --git a/tests/integration/external/guzzle5/test_dt.php b/tests/integration/external/guzzle5/test_dt.php index 4992d91f4..bbd19ba7b 100644 --- a/tests/integration/external/guzzle5/test_dt.php +++ b/tests/integration/external/guzzle5/test_dt.php @@ -41,6 +41,7 @@ [{"name":"OtherTransactionTotalTime"}, [1, "??", "??", "??", "??", "??"]], [{"name":"OtherTransactionTotalTime/php__FILE__"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/library/Guzzle 4-5/detected"}, [1, 0, 0, 0, 0, 0]], + [{"name":"Supportability/library/Autoloader/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Unsupported/curl_setopt/CURLOPT_HEADERFUNCTION/closure"}, [1, 0, 0, 0, 0, 0]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/all"}, [1, "??", "??", "??", "??", "??"]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/allOther"}, [1, "??", "??", "??", "??", "??"]], diff --git a/tests/integration/external/guzzle5/test_dt_newrelic_header_disabled.php b/tests/integration/external/guzzle5/test_dt_newrelic_header_disabled.php index 0a3352ba6..de432cacb 100644 --- a/tests/integration/external/guzzle5/test_dt_newrelic_header_disabled.php +++ b/tests/integration/external/guzzle5/test_dt_newrelic_header_disabled.php @@ -42,6 +42,7 @@ [{"name":"OtherTransactionTotalTime"}, [1, "??", "??", "??", "??", "??"]], [{"name":"OtherTransactionTotalTime/php__FILE__"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/library/Guzzle 4-5/detected"}, [1, 0, 0, 0, 0, 0]], + [{"name":"Supportability/library/Autoloader/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Unsupported/curl_setopt/CURLOPT_HEADERFUNCTION/closure"}, [1, 0, 0, 0, 0, 0]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/all"}, [1, "??", "??", "??", "??", "??"]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/allOther"}, [1, "??", "??", "??", "??", "??"]], diff --git a/tests/integration/external/guzzle5/test_dt_synthetics.php b/tests/integration/external/guzzle5/test_dt_synthetics.php index 042f9f3eb..e23f4f466 100644 --- a/tests/integration/external/guzzle5/test_dt_synthetics.php +++ b/tests/integration/external/guzzle5/test_dt_synthetics.php @@ -72,6 +72,7 @@ [{"name":"WebTransactionTotalTime/Uri__FILE__"}, [1, "??", "??", "??", "??", "??"]], [{"name":"HttpDispatcher"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/library/Guzzle 4-5/detected"}, [1, 0, 0, 0, 0, 0]], + [{"name":"Supportability/library/Autoloader/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Unsupported/curl_setopt/CURLOPT_HEADERFUNCTION/closure"}, [3, 0, 0, 0, 0, 0]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/all"}, [1, "??", "??", "??", "??", "??"]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/allWeb"}, [1, "??", "??", "??", "??", "??"]], diff --git a/tests/integration/external/guzzle5/test_dt_synthetics_logging_off.php b/tests/integration/external/guzzle5/test_dt_synthetics_logging_off.php index 559517104..8bc244e3b 100644 --- a/tests/integration/external/guzzle5/test_dt_synthetics_logging_off.php +++ b/tests/integration/external/guzzle5/test_dt_synthetics_logging_off.php @@ -75,6 +75,7 @@ [{"name":"WebTransactionTotalTime/Uri__FILE__"}, [1, "??", "??", "??", "??", "??"]], [{"name":"HttpDispatcher"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/library/Guzzle 4-5/detected"}, [1, 0, 0, 0, 0, 0]], + [{"name":"Supportability/library/Autoloader/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Unsupported/curl_setopt/CURLOPT_HEADERFUNCTION/closure"}, [3, 0, 0, 0, 0, 0]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/all"}, [1, "??", "??", "??", "??", "??"]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/allWeb"}, [1, "??", "??", "??", "??", "??"]], diff --git a/tests/integration/external/guzzle5/test_no_cat_no_dt.php b/tests/integration/external/guzzle5/test_no_cat_no_dt.php index 241a01fa9..93a3e477e 100644 --- a/tests/integration/external/guzzle5/test_no_cat_no_dt.php +++ b/tests/integration/external/guzzle5/test_no_cat_no_dt.php @@ -43,6 +43,7 @@ [{"name":"OtherTransactionTotalTime"}, [1, "??", "??", "??", "??", "??"]], [{"name":"OtherTransactionTotalTime/php__FILE__"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/library/Guzzle 4-5/detected"}, [1, 0, 0, 0, 0, 0]], + [{"name":"Supportability/library/Autoloader/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Logging/Forwarding/PHP/enabled"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Logging/Metrics/PHP/enabled"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Logging/LocalDecorating/PHP/disabled"},[1, "??", "??", "??", "??", "??"]], diff --git a/tests/integration/external/guzzle6/test_cat.php b/tests/integration/external/guzzle6/test_cat.php index 834185ad4..e097dabbe 100644 --- a/tests/integration/external/guzzle6/test_cat.php +++ b/tests/integration/external/guzzle6/test_cat.php @@ -54,6 +54,8 @@ [{"name":"Supportability/PHP/package/guzzlehttp/guzzle/6/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/library/Guzzle 6/detected"}, [1, 0, 0, 0, 0, 0]], [{"name":"Supportability/Unsupported/curl_setopt/CURLOPT_HEADERFUNCTION/closure"}, [3, 0, 0, 0, 0, 0]], + [{"name":"Supportability/library/Autoloader/detected"}, [1, "??", "??", "??", "??", "??"]], + [{"name":"Supportability/library/Composer/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Logging/Forwarding/PHP/enabled"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Logging/Metrics/PHP/enabled"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Logging/LocalDecorating/PHP/disabled"},[1, "??", "??", "??", "??", "??"]], diff --git a/tests/integration/external/guzzle6/test_dt.php b/tests/integration/external/guzzle6/test_dt.php index d405abdfa..59e0c70c0 100644 --- a/tests/integration/external/guzzle6/test_dt.php +++ b/tests/integration/external/guzzle6/test_dt.php @@ -44,6 +44,8 @@ [{"name":"OtherTransactionTotalTime/php__FILE__"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/PHP/package/guzzlehttp/guzzle/6/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/library/Guzzle 6/detected"}, [1, 0, 0, 0, 0, 0]], + [{"name":"Supportability/library/Autoloader/detected"}, [1, "??", "??", "??", "??", "??"]], + [{"name":"Supportability/library/Composer/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Unsupported/curl_setopt/CURLOPT_HEADERFUNCTION/closure"}, [3, 0, 0, 0, 0, 0]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/all"}, [1, "??", "??", "??", "??", "??"]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/allOther"}, [1, "??", "??", "??", "??", "??"]], diff --git a/tests/integration/external/guzzle6/test_dt_newrelic_header_disabled.php b/tests/integration/external/guzzle6/test_dt_newrelic_header_disabled.php index 290ca52e7..18efa6d6d 100644 --- a/tests/integration/external/guzzle6/test_dt_newrelic_header_disabled.php +++ b/tests/integration/external/guzzle6/test_dt_newrelic_header_disabled.php @@ -45,6 +45,8 @@ [{"name":"OtherTransactionTotalTime/php__FILE__"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/PHP/package/guzzlehttp/guzzle/6/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/library/Guzzle 6/detected"}, [1, 0, 0, 0, 0, 0]], + [{"name":"Supportability/library/Autoloader/detected"}, [1, "??", "??", "??", "??", "??"]], + [{"name":"Supportability/library/Composer/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Unsupported/curl_setopt/CURLOPT_HEADERFUNCTION/closure"}, [3, 0, 0, 0, 0, 0]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/all"}, [1, "??", "??", "??", "??", "??"]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/allOther"}, [1, "??", "??", "??", "??", "??"]], diff --git a/tests/integration/external/guzzle6/test_dt_synthetics.php b/tests/integration/external/guzzle6/test_dt_synthetics.php index ccfc8ac31..6fb8de3b7 100644 --- a/tests/integration/external/guzzle6/test_dt_synthetics.php +++ b/tests/integration/external/guzzle6/test_dt_synthetics.php @@ -67,6 +67,8 @@ [{"name":"HttpDispatcher"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/PHP/package/guzzlehttp/guzzle/6/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/library/Guzzle 6/detected"}, [1, 0, 0, 0, 0, 0]], + [{"name":"Supportability/library/Autoloader/detected"}, [1, "??", "??", "??", "??", "??"]], + [{"name":"Supportability/library/Composer/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Unsupported/curl_setopt/CURLOPT_HEADERFUNCTION/closure"}, [3, 0, 0, 0, 0, 0]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/all"}, [1, "??", "??", "??", "??", "??"]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/allWeb"}, [1, "??", "??", "??", "??", "??"]], diff --git a/tests/integration/external/guzzle6/test_dt_synthetics_logging_off.php b/tests/integration/external/guzzle6/test_dt_synthetics_logging_off.php index 3981082e5..f27c17f9e 100644 --- a/tests/integration/external/guzzle6/test_dt_synthetics_logging_off.php +++ b/tests/integration/external/guzzle6/test_dt_synthetics_logging_off.php @@ -70,6 +70,8 @@ [{"name":"HttpDispatcher"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/PHP/package/guzzlehttp/guzzle/6/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/library/Guzzle 6/detected"}, [1, 0, 0, 0, 0, 0]], + [{"name":"Supportability/library/Autoloader/detected"}, [1, "??", "??", "??", "??", "??"]], + [{"name":"Supportability/library/Composer/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Unsupported/curl_setopt/CURLOPT_HEADERFUNCTION/closure"}, [3, 0, 0, 0, 0, 0]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/all"}, [1, "??", "??", "??", "??", "??"]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/allWeb"}, [1, "??", "??", "??", "??", "??"]], diff --git a/tests/integration/external/guzzle6/test_no_cat_no_dt.php b/tests/integration/external/guzzle6/test_no_cat_no_dt.php index 8d42dff85..39db807a9 100644 --- a/tests/integration/external/guzzle6/test_no_cat_no_dt.php +++ b/tests/integration/external/guzzle6/test_no_cat_no_dt.php @@ -44,6 +44,8 @@ [{"name":"OtherTransactionTotalTime/php__FILE__"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/PHP/package/guzzlehttp/guzzle/6/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/library/Guzzle 6/detected"}, [1, 0, 0, 0, 0, 0]], + [{"name":"Supportability/library/Autoloader/detected"}, [1, "??", "??", "??", "??", "??"]], + [{"name":"Supportability/library/Composer/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Logging/Forwarding/PHP/enabled"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Logging/Metrics/PHP/enabled"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Logging/LocalDecorating/PHP/disabled"},[1, "??", "??", "??", "??", "??"]], diff --git a/tests/integration/external/guzzle7/test_cat.php b/tests/integration/external/guzzle7/test_cat.php index c865cc94f..7f081b47e 100644 --- a/tests/integration/external/guzzle7/test_cat.php +++ b/tests/integration/external/guzzle7/test_cat.php @@ -54,6 +54,8 @@ [{"name":"Supportability/PHP/package/guzzlehttp/guzzle/7/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/library/Guzzle 6/detected"}, [1, 0, 0, 0, 0, 0]], [{"name":"Supportability/Unsupported/curl_setopt/CURLOPT_HEADERFUNCTION/closure"}, [3, 0, 0, 0, 0, 0]], + [{"name":"Supportability/library/Autoloader/detected"}, [1, "??", "??", "??", "??", "??"]], + [{"name":"Supportability/library/Composer/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Logging/Forwarding/PHP/enabled"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Logging/Metrics/PHP/enabled"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Logging/LocalDecorating/PHP/disabled"}, [1, "??", "??", "??", "??", "??"]], diff --git a/tests/integration/external/guzzle7/test_dt.php b/tests/integration/external/guzzle7/test_dt.php index 3b4375c5d..d21811b98 100644 --- a/tests/integration/external/guzzle7/test_dt.php +++ b/tests/integration/external/guzzle7/test_dt.php @@ -44,6 +44,8 @@ [{"name":"OtherTransactionTotalTime/php__FILE__"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/PHP/package/guzzlehttp/guzzle/7/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/library/Guzzle 6/detected"}, [1, 0, 0, 0, 0, 0]], + [{"name":"Supportability/library/Autoloader/detected"}, [1, "??", "??", "??", "??", "??"]], + [{"name":"Supportability/library/Composer/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Unsupported/curl_setopt/CURLOPT_HEADERFUNCTION/closure"}, [3, 0, 0, 0, 0, 0]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/all"}, [1, "??", "??", "??", "??", "??"]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/allOther"}, [1, "??", "??", "??", "??", "??"]], diff --git a/tests/integration/external/guzzle7/test_dt_newrelic_header_disabled.php b/tests/integration/external/guzzle7/test_dt_newrelic_header_disabled.php index 3f98fd74d..f609c203e 100644 --- a/tests/integration/external/guzzle7/test_dt_newrelic_header_disabled.php +++ b/tests/integration/external/guzzle7/test_dt_newrelic_header_disabled.php @@ -44,7 +44,9 @@ [{"name":"OtherTransactionTotalTime"}, [1, "??", "??", "??", "??", "??"]], [{"name":"OtherTransactionTotalTime/php__FILE__"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/PHP/package/guzzlehttp/guzzle/7/detected"}, [1, "??", "??", "??", "??", "??"]], - [{"name":"Supportability/library/Guzzle 6/detected"}, [1, 0, 0, 0, 0, 0]], + [{"name":"Supportability/library/Guzzle 6/detected"}, [1, 0, 0, 0, 0, 0]], + [{"name":"Supportability/library/Autoloader/detected"}, [1, "??", "??", "??", "??", "??"]], + [{"name":"Supportability/library/Composer/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Unsupported/curl_setopt/CURLOPT_HEADERFUNCTION/closure"}, [3, 0, 0, 0, 0, 0]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/all"}, [1, "??", "??", "??", "??", "??"]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/allOther"}, [1, "??", "??", "??", "??", "??"]], diff --git a/tests/integration/external/guzzle7/test_dt_synthetics.php b/tests/integration/external/guzzle7/test_dt_synthetics.php index 18541bfad..0a6c63116 100644 --- a/tests/integration/external/guzzle7/test_dt_synthetics.php +++ b/tests/integration/external/guzzle7/test_dt_synthetics.php @@ -67,6 +67,8 @@ [{"name":"HttpDispatcher"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/PHP/package/guzzlehttp/guzzle/7/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/library/Guzzle 6/detected"}, [1, 0, 0, 0, 0, 0]], + [{"name":"Supportability/library/Autoloader/detected"}, [1, "??", "??", "??", "??", "??"]], + [{"name":"Supportability/library/Composer/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Unsupported/curl_setopt/CURLOPT_HEADERFUNCTION/closure"}, [3, 0, 0, 0, 0, 0]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/all"}, [1, "??", "??", "??", "??", "??"]], [{"name":"DurationByCaller/Unknown/Unknown/Unknown/Unknown/allWeb"}, [1, "??", "??", "??", "??", "??"]], diff --git a/tests/integration/external/guzzle7/test_no_cat_no_dt.php b/tests/integration/external/guzzle7/test_no_cat_no_dt.php index 5d6413715..1c3e39699 100644 --- a/tests/integration/external/guzzle7/test_no_cat_no_dt.php +++ b/tests/integration/external/guzzle7/test_no_cat_no_dt.php @@ -44,6 +44,8 @@ [{"name":"OtherTransactionTotalTime/php__FILE__"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/PHP/package/guzzlehttp/guzzle/7/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/library/Guzzle 6/detected"}, [1, 0, 0, 0, 0, 0]], + [{"name":"Supportability/library/Autoloader/detected"}, [1, "??", "??", "??", "??", "??"]], + [{"name":"Supportability/library/Composer/detected"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Logging/Forwarding/PHP/enabled"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Logging/Metrics/PHP/enabled"}, [1, "??", "??", "??", "??", "??"]], [{"name":"Supportability/Logging/LocalDecorating/PHP/disabled"}, [1, "??", "??", "??", "??", "??"]], diff --git a/tests/integration/jit/function/test_span_class_function.php b/tests/integration/jit/function/test_span_class_function.php index 5dbce791c..fe8e38d1c 100644 --- a/tests/integration/jit/function/test_span_class_function.php +++ b/tests/integration/jit/function/test_span_class_function.php @@ -244,6 +244,7 @@ newrelic_add_custom_tracer('Classname::functionName'); function main() { + time_nanosleep(0, 50000); // force non-zero duration for the segment not to be dropped. echo 'Hello'; } main(); diff --git a/tests/integration/jit/tracing/test_span_class_function.php b/tests/integration/jit/tracing/test_span_class_function.php index 835d7649a..5a520f211 100644 --- a/tests/integration/jit/tracing/test_span_class_function.php +++ b/tests/integration/jit/tracing/test_span_class_function.php @@ -243,6 +243,7 @@ newrelic_add_custom_tracer('Classname::functionName'); function main() { + time_nanosleep(0, 50000); // force non-zero duration for the segment not to be dropped. echo 'Hello'; } main(); diff --git a/tests/integration/lang/trampoline/test_trampoline_02.php b/tests/integration/lang/trampoline/test_trampoline_02.php index 65b331768..a7a00cada 100644 --- a/tests/integration/lang/trampoline/test_trampoline_02.php +++ b/tests/integration/lang/trampoline/test_trampoline_02.php @@ -77,6 +77,7 @@ $anon = new class() { function execute() { + time_nanosleep(0, 50000); // force non-zero duration for the segment not to be dropped. new ReflectionClass('Wrapper'); } }; @@ -84,6 +85,7 @@ function execute() $anon2 = new class() { function execute() { + time_nanosleep(0, 50000); // force non-zero duration for the segment not to be dropped. new ReflectionClass('Wrapper'); } }; diff --git a/tests/integration/opcache/disabled/test_span_class_function.php b/tests/integration/opcache/disabled/test_span_class_function.php index 4a693e689..d3438f6ec 100644 --- a/tests/integration/opcache/disabled/test_span_class_function.php +++ b/tests/integration/opcache/disabled/test_span_class_function.php @@ -245,6 +245,7 @@ newrelic_add_custom_tracer('Classname::functionName'); function main() { + time_nanosleep(0, 50000); // force non-zero duration for the segment not to be dropped. echo 'Hello'; } main();