diff --git a/.circleci/config.yml b/.circleci/config.yml index f0ef86756ae88..c2cebc0c3550b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -26,175 +26,175 @@ jobs: PDO_PGSQL_TEST_DSN: 'pgsql:host=127.0.0.1 port=5432 dbname=test user=postgres password=postgres' steps: - checkout - - run: - name: apt - command: | - export DEBIAN_FRONTEND=noninteractive - sudo apt-get update -y - sudo apt-get install -y \ - gcc \ - g++ \ - autoconf \ - bison \ - re2c \ - locales \ - locales-all \ - ldap-utils \ - openssl \ - slapd \ - libgmp-dev \ - libicu-dev \ - libtidy-dev \ - libenchant-2-dev \ - libaspell-dev \ - libpspell-dev \ - libsasl2-dev \ - libxpm-dev \ - libzip-dev \ - libbz2-dev \ - libsqlite3-dev \ - libwebp-dev \ - libonig-dev \ - libkrb5-dev \ - libgssapi-krb5-2 \ - libcurl4-openssl-dev \ - libxml2-dev \ - libxslt1-dev \ - libpq-dev \ - libreadline-dev \ - libldap2-dev \ - libsodium-dev \ - libargon2-0-dev \ - libmm-dev \ - libsnmp-dev \ - snmpd \ - `#snmp-mibs-downloader` \ - freetds-dev \ - `#unixodbc-dev` \ - libc-client-dev \ - dovecot-core \ - dovecot-pop3d \ - dovecot-imapd \ - sendmail \ - firebird-dev \ - liblmdb-dev \ - libtokyocabinet-dev \ - libdb-dev \ - libqdbm-dev \ - libjpeg-dev \ - libpng-dev \ - libfreetype6-dev - - run: - name: ./configure - command: | - ./buildconf -f - ./configure \ - --enable-debug \ - --enable-zts \ - --enable-option-checking=fatal \ - --prefix=/usr \ - --enable-phpdbg \ - --enable-fpm \ - --enable-opcache \ - --with-pdo-mysql=mysqlnd \ - --with-mysqli=mysqlnd \ - --with-pgsql \ - --with-pdo-pgsql \ - --with-pdo-sqlite \ - --enable-intl \ - --without-pear \ - --enable-gd \ - --with-jpeg \ - --with-webp \ - --with-freetype \ - --with-xpm \ - --enable-exif \ - --with-zip \ - --with-zlib \ - --with-zlib-dir=/usr \ - --enable-soap \ - --enable-xmlreader \ - --with-xsl \ - --with-tidy \ - --enable-sysvsem \ - --enable-sysvshm \ - --enable-shmop \ - --enable-pcntl \ - --with-readline \ - --enable-mbstring \ - --with-curl \ - --with-gettext \ - --enable-sockets \ - --with-bz2 \ - --with-openssl \ - --with-gmp \ - --enable-bcmath \ - --enable-calendar \ - --enable-ftp \ - --with-pspell=/usr \ - --with-enchant=/usr \ - --with-kerberos \ - --enable-sysvmsg \ - --with-ffi \ - --enable-zend-test \ - --enable-dl-test=shared \ - --with-ldap \ - --with-ldap-sasl \ - --with-password-argon2 \ - --with-mhash \ - --with-sodium \ - --enable-dba \ - --with-cdb \ - --enable-flatfile \ - --enable-inifile \ - --with-tcadb \ - --with-lmdb \ - --with-qdbm \ - --with-snmp \ - `#--with-unixODBC` \ - --with-imap \ - --with-kerberos \ - --with-imap-ssl \ - `#--with-pdo-odbc=unixODBC,/usr` \ - `#--with-pdo-oci=shared,instantclient,/opt/oracle/instantclient` \ - `#--with-oci8=shared,instantclient,/opt/oracle/instantclient` \ - --with-config-file-path=/etc \ - --with-config-file-scan-dir=/etc/php.d \ - --with-pdo-firebird \ - `#--with-pdo-dblib` \ - --disable-phpdbg \ - `#--enable-werror` - - run: - name: make - no_output_timeout: 30m - command: make -j2 > /dev/null - - run: - name: make install - command: | - sudo make install - sudo mkdir -p /etc/php.d - sudo chmod 777 /etc/php.d - echo opcache.enable_cli=1 > /etc/php.d/opcache.ini - echo opcache.protect_memory=1 >> /etc/php.d/opcache.ini - - run: - name: Test - no_output_timeout: 30m - command: | - sapi/cli/php run-tests.php \ - -d zend_extension=opcache.so \ - -d opcache.enable_cli=1 \ - -d opcache.jit_buffer_size=16M \ - -d opcache.jit=tracing \ - -d zend_test.observer.enabled=1 \ - -d zend_test.observer.show_output=0 \ - -P -q -x -j2 \ - -g FAIL,BORK,LEAK,XLEAK \ - --no-progress \ - --offline \ - --show-diff \ - --show-slow 1000 \ - --set-timeout 120 \ - --repeat 2 + # - run: + # name: apt + # command: | + # export DEBIAN_FRONTEND=noninteractive + # sudo apt-get update -y + # sudo apt-get install -y \ + # gcc \ + # g++ \ + # autoconf \ + # bison \ + # re2c \ + # locales \ + # locales-all \ + # ldap-utils \ + # openssl \ + # slapd \ + # libgmp-dev \ + # libicu-dev \ + # libtidy-dev \ + # libenchant-2-dev \ + # libaspell-dev \ + # libpspell-dev \ + # libsasl2-dev \ + # libxpm-dev \ + # libzip-dev \ + # libbz2-dev \ + # libsqlite3-dev \ + # libwebp-dev \ + # libonig-dev \ + # libkrb5-dev \ + # libgssapi-krb5-2 \ + # libcurl4-openssl-dev \ + # libxml2-dev \ + # libxslt1-dev \ + # libpq-dev \ + # libreadline-dev \ + # libldap2-dev \ + # libsodium-dev \ + # libargon2-0-dev \ + # libmm-dev \ + # libsnmp-dev \ + # snmpd \ + # `#snmp-mibs-downloader` \ + # freetds-dev \ + # `#unixodbc-dev` \ + # libc-client-dev \ + # dovecot-core \ + # dovecot-pop3d \ + # dovecot-imapd \ + # sendmail \ + # firebird-dev \ + # liblmdb-dev \ + # libtokyocabinet-dev \ + # libdb-dev \ + # libqdbm-dev \ + # libjpeg-dev \ + # libpng-dev \ + # libfreetype6-dev + # - run: + # name: ./configure + # command: | + # ./buildconf -f + # ./configure \ + # --enable-debug \ + # --enable-zts \ + # --enable-option-checking=fatal \ + # --prefix=/usr \ + # --enable-phpdbg \ + # --enable-fpm \ + # --enable-opcache \ + # --with-pdo-mysql=mysqlnd \ + # --with-mysqli=mysqlnd \ + # --with-pgsql \ + # --with-pdo-pgsql \ + # --with-pdo-sqlite \ + # --enable-intl \ + # --without-pear \ + # --enable-gd \ + # --with-jpeg \ + # --with-webp \ + # --with-freetype \ + # --with-xpm \ + # --enable-exif \ + # --with-zip \ + # --with-zlib \ + # --with-zlib-dir=/usr \ + # --enable-soap \ + # --enable-xmlreader \ + # --with-xsl \ + # --with-tidy \ + # --enable-sysvsem \ + # --enable-sysvshm \ + # --enable-shmop \ + # --enable-pcntl \ + # --with-readline \ + # --enable-mbstring \ + # --with-curl \ + # --with-gettext \ + # --enable-sockets \ + # --with-bz2 \ + # --with-openssl \ + # --with-gmp \ + # --enable-bcmath \ + # --enable-calendar \ + # --enable-ftp \ + # --with-pspell=/usr \ + # --with-enchant=/usr \ + # --with-kerberos \ + # --enable-sysvmsg \ + # --with-ffi \ + # --enable-zend-test \ + # --enable-dl-test=shared \ + # --with-ldap \ + # --with-ldap-sasl \ + # --with-password-argon2 \ + # --with-mhash \ + # --with-sodium \ + # --enable-dba \ + # --with-cdb \ + # --enable-flatfile \ + # --enable-inifile \ + # --with-tcadb \ + # --with-lmdb \ + # --with-qdbm \ + # --with-snmp \ + # `#--with-unixODBC` \ + # --with-imap \ + # --with-kerberos \ + # --with-imap-ssl \ + # `#--with-pdo-odbc=unixODBC,/usr` \ + # `#--with-pdo-oci=shared,instantclient,/opt/oracle/instantclient` \ + # `#--with-oci8=shared,instantclient,/opt/oracle/instantclient` \ + # --with-config-file-path=/etc \ + # --with-config-file-scan-dir=/etc/php.d \ + # --with-pdo-firebird \ + # `#--with-pdo-dblib` \ + # --disable-phpdbg \ + # `#--enable-werror` + # - run: + # name: make + # no_output_timeout: 30m + # command: make -j2 > /dev/null + # - run: + # name: make install + # command: | + # sudo make install + # sudo mkdir -p /etc/php.d + # sudo chmod 777 /etc/php.d + # echo opcache.enable_cli=1 > /etc/php.d/opcache.ini + # echo opcache.protect_memory=1 >> /etc/php.d/opcache.ini + # - run: + # name: Test + # no_output_timeout: 30m + # command: | + # sapi/cli/php run-tests.php \ + # -d zend_extension=opcache.so \ + # -d opcache.enable_cli=1 \ + # -d opcache.jit_buffer_size=16M \ + # -d opcache.jit=tracing \ + # -d zend_test.observer.enabled=1 \ + # -d zend_test.observer.show_output=0 \ + # -P -q -x -j2 \ + # -g FAIL,BORK,LEAK,XLEAK \ + # --no-progress \ + # --offline \ + # --show-diff \ + # --show-slow 1000 \ + # --set-timeout 120 \ + # --repeat 2 workflows: push-workflow: diff --git a/.github/actions/apt-x64/action.yml b/.github/actions/apt-x64/action.yml index 98c7003175d73..ee34ef3ed2955 100644 --- a/.github/actions/apt-x64/action.yml +++ b/.github/actions/apt-x64/action.yml @@ -29,6 +29,8 @@ runs: ldap-utils \ openssl \ slapd \ + bind9 \ + bind9utils \ language-pack-de \ libgmp-dev \ libicu-dev \ diff --git a/.github/actions/setup-x64/action.yml b/.github/actions/setup-x64/action.yml index e860f79b5ad47..20fd3994920af 100644 --- a/.github/actions/setup-x64/action.yml +++ b/.github/actions/setup-x64/action.yml @@ -6,6 +6,9 @@ runs: run: | set -x + sudo ./ext/standard/tests/dns/bind-start.sh + sudo ./ext/standard/tests/dns/resolv-setup.sh + sudo service slapd start docker exec sql1 /opt/mssql-tools18/bin/sqlcmd -S 127.0.0.1 -U SA -C -P "" -Q "create login pdo_test with password='password', check_policy=off; create user pdo_test for login pdo_test; grant alter, control to pdo_test;" docker exec sql1 /opt/mssql-tools18/bin/sqlcmd -S 127.0.0.1 -U SA -C -P "" -Q "create login odbc_test with password='password', check_policy=off; create user odbc_test for login odbc_test; grant alter, control, delete to odbc_test;" diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index f086c24a5366b..a1cf362cbcb49 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -134,215 +134,215 @@ jobs: - name: Verify generated files are up to date if: ${{ !matrix.asan }} uses: ./.github/actions/verify-generated-files - LINUX_X32: - if: github.repository == 'php/php-src' || github.event_name == 'pull_request' - name: LINUX_X32_DEBUG_ZTS - runs-on: ubuntu-latest - container: - image: ubuntu:22.04 - env: - MYSQL_TEST_HOST: mysql - PDO_MYSQL_TEST_DSN: mysql:host=mysql;dbname=test - PDO_MYSQL_TEST_HOST: mysql - services: - mysql: - image: mysql:8.3 - ports: - - 3306:3306 - env: - MYSQL_DATABASE: test - MYSQL_ROOT_PASSWORD: root - steps: - - name: git checkout - uses: actions/checkout@v5 - - name: apt - uses: ./.github/actions/apt-x32 - - name: ccache - uses: hendrikmuhs/ccache-action@v1.2 - with: - key: "${{github.job}}-${{hashFiles('main/php_version.h')}}" - append-timestamp: false - - name: ./configure - uses: ./.github/actions/configure-x32 - with: - configurationParameters: >- - --enable-debug - --enable-zts - - name: make - run: make -j$(/usr/bin/nproc) >/dev/null - - name: make install - uses: ./.github/actions/install-linux-x32 - - name: Test Tracing JIT - uses: ./.github/actions/test-linux - with: - jitType: tracing - runTestsParameters: >- - -d zend_extension=opcache.so - -d opcache.enable_cli=1 - MACOS_DEBUG_NTS: - if: github.repository == 'php/php-src' || github.event_name == 'pull_request' - runs-on: macos-14 - steps: - - name: git checkout - uses: actions/checkout@v5 - - name: brew - uses: ./.github/actions/brew - - name: ccache - uses: hendrikmuhs/ccache-action@v1.2 - with: - key: "${{github.job}}-${{hashFiles('main/php_version.h')}}" - append-timestamp: false - save: ${{ github.event_name != 'pull_request' }} - - name: ./configure - uses: ./.github/actions/configure-macos - with: - configurationParameters: --enable-debug --disable-zts - - name: make - run: |- - export PATH="$(brew --prefix)/opt/bison/bin:$PATH" - make -j$(sysctl -n hw.logicalcpu) >/dev/null - - name: make install - run: sudo make install - - name: Test Tracing JIT - uses: ./.github/actions/test-macos - with: - jitType: tracing - runTestsParameters: >- - -d zend_extension=opcache.so - -d opcache.enable_cli=1 - -d opcache.protect_memory=1 - - name: Verify generated files are up to date - uses: ./.github/actions/verify-generated-files - WINDOWS: - if: github.repository == 'php/php-src' || github.event_name == 'pull_request' - name: WINDOWS_X64_ZTS - runs-on: windows-2022 - env: - PHP_BUILD_CACHE_BASE_DIR: C:\build-cache - PHP_BUILD_OBJ_DIR: C:\obj - PHP_BUILD_CACHE_SDK_DIR: C:\build-cache\sdk - PHP_BUILD_SDK_BRANCH: php-sdk-2.3.0 - PHP_BUILD_CRT: vs16 - PLATFORM: x64 - THREAD_SAFE: "1" - INTRINSICS: AVX2 - PARALLEL: -j2 - OPCACHE: "1" - steps: - - name: git config - run: git config --global core.autocrlf false && git config --global core.eol lf - - name: git checkout - uses: actions/checkout@v5 - - name: Setup - uses: ./.github/actions/setup-windows - - name: Build - run: .github/scripts/windows/build.bat - - name: Test - run: .github/scripts/windows/test.bat - BENCHMARKING: - name: BENCHMARKING - if: github.repository == 'php/php-src' || github.event_name == 'pull_request' - runs-on: ubuntu-22.04 - steps: - - name: git checkout - uses: actions/checkout@v5 - with: - fetch-depth: 0 - - name: apt - run: | - set -x - sudo apt-get update - sudo apt-get install \ - bison \ - libgmp-dev \ - libonig-dev \ - libsqlite3-dev \ - openssl \ - re2c \ - valgrind - - name: ccache - uses: hendrikmuhs/ccache-action@v1.2 - with: - key: "${{github.job}}-${{hashFiles('main/php_version.h')}}" - append-timestamp: false - save: ${{ github.event_name != 'pull_request' }} - - name: ./configure - run: | - set -x - ./buildconf --force - ./configure \ - --disable-debug \ - --enable-mbstring \ - --enable-opcache \ - --enable-option-checking=fatal \ - --enable-sockets \ - --enable-werror \ - --prefix=/usr \ - --with-config-file-scan-dir=/etc/php.d \ - --with-gmp \ - --with-mysqli=mysqlnd \ - --with-openssl \ - --with-pdo-sqlite \ - --with-valgrind - - name: make - run: make -j$(/usr/bin/nproc) >/dev/null - - name: make install - run: | - set -x - sudo make install - sudo mkdir -p /etc/php.d - sudo chmod 777 /etc/php.d - echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini - echo zend_extension=opcache.so >> /etc/php.d/opcache.ini - echo opcache.enable=1 >> /etc/php.d/opcache.ini - echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini - - name: Setup - run: | - git config --global user.name "Benchmark" - git config --global user.email "benchmark@php.net" - sudo service mysql start - mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS wordpress" - mysql -uroot -proot -e "CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'wordpress'; FLUSH PRIVILEGES;" - mysql -uroot -proot -e "GRANT ALL PRIVILEGES ON *.* TO 'wordpress'@'localhost' WITH GRANT OPTION;" - - name: git checkout benchmarking-data - uses: actions/checkout@v5 - with: - repository: php/benchmarking-data - ssh-key: ${{ secrets.BENCHMARKING_DATA_DEPLOY_KEY }} - path: benchmark/repos/data - - name: Benchmark - run: php benchmark/benchmark.php true - - name: Store result - if: github.event_name == 'push' - run: | - set -x - cd benchmark/repos/data - git pull --autostash - if [ -e ".git/MERGE_HEAD" ]; then - echo "Merging, can't proceed" - exit 1 - fi - git add . - if git diff --cached --quiet; then - exit 0 - fi - git commit -m "Add result for ${{ github.repository }}@${{ github.sha }}" - git push - - name: Show diff - if: github.event_name == 'pull_request' - run: |- - set -x - php benchmark/generate_diff.php \ - ${{ github.sha }} \ - $(git merge-base ${{ github.event.pull_request.base.sha }} ${{ github.sha }}) \ - > $GITHUB_STEP_SUMMARY - FREEBSD: - if: github.repository == 'php/php-src' || github.event_name == 'pull_request' - name: FREEBSD - runs-on: ubuntu-latest - timeout-minutes: 50 - steps: - - name: git checkout - uses: actions/checkout@v5 - - name: FreeBSD - uses: ./.github/actions/freebsd + # LINUX_X32: + # if: github.repository == 'php/php-src' || github.event_name == 'pull_request' + # name: LINUX_X32_DEBUG_ZTS + # runs-on: ubuntu-latest + # container: + # image: ubuntu:22.04 + # env: + # MYSQL_TEST_HOST: mysql + # PDO_MYSQL_TEST_DSN: mysql:host=mysql;dbname=test + # PDO_MYSQL_TEST_HOST: mysql + # services: + # mysql: + # image: mysql:8.3 + # ports: + # - 3306:3306 + # env: + # MYSQL_DATABASE: test + # MYSQL_ROOT_PASSWORD: root + # steps: + # - name: git checkout + # uses: actions/checkout@v5 + # - name: apt + # uses: ./.github/actions/apt-x32 + # - name: ccache + # uses: hendrikmuhs/ccache-action@v1.2 + # with: + # key: "${{github.job}}-${{hashFiles('main/php_version.h')}}" + # append-timestamp: false + # - name: ./configure + # uses: ./.github/actions/configure-x32 + # with: + # configurationParameters: >- + # --enable-debug + # --enable-zts + # - name: make + # run: make -j$(/usr/bin/nproc) >/dev/null + # - name: make install + # uses: ./.github/actions/install-linux-x32 + # - name: Test Tracing JIT + # uses: ./.github/actions/test-linux + # with: + # jitType: tracing + # runTestsParameters: >- + # -d zend_extension=opcache.so + # -d opcache.enable_cli=1 + # MACOS_DEBUG_NTS: + # if: github.repository == 'php/php-src' || github.event_name == 'pull_request' + # runs-on: macos-14 + # steps: + # - name: git checkout + # uses: actions/checkout@v5 + # - name: brew + # uses: ./.github/actions/brew + # - name: ccache + # uses: hendrikmuhs/ccache-action@v1.2 + # with: + # key: "${{github.job}}-${{hashFiles('main/php_version.h')}}" + # append-timestamp: false + # save: ${{ github.event_name != 'pull_request' }} + # - name: ./configure + # uses: ./.github/actions/configure-macos + # with: + # configurationParameters: --enable-debug --disable-zts + # - name: make + # run: |- + # export PATH="$(brew --prefix)/opt/bison/bin:$PATH" + # make -j$(sysctl -n hw.logicalcpu) >/dev/null + # - name: make install + # run: sudo make install + # - name: Test Tracing JIT + # uses: ./.github/actions/test-macos + # with: + # jitType: tracing + # runTestsParameters: >- + # -d zend_extension=opcache.so + # -d opcache.enable_cli=1 + # -d opcache.protect_memory=1 + # - name: Verify generated files are up to date + # uses: ./.github/actions/verify-generated-files + # WINDOWS: + # if: github.repository == 'php/php-src' || github.event_name == 'pull_request' + # name: WINDOWS_X64_ZTS + # runs-on: windows-2022 + # env: + # PHP_BUILD_CACHE_BASE_DIR: C:\build-cache + # PHP_BUILD_OBJ_DIR: C:\obj + # PHP_BUILD_CACHE_SDK_DIR: C:\build-cache\sdk + # PHP_BUILD_SDK_BRANCH: php-sdk-2.3.0 + # PHP_BUILD_CRT: vs16 + # PLATFORM: x64 + # THREAD_SAFE: "1" + # INTRINSICS: AVX2 + # PARALLEL: -j2 + # OPCACHE: "1" + # steps: + # - name: git config + # run: git config --global core.autocrlf false && git config --global core.eol lf + # - name: git checkout + # uses: actions/checkout@v5 + # - name: Setup + # uses: ./.github/actions/setup-windows + # - name: Build + # run: .github/scripts/windows/build.bat + # - name: Test + # run: .github/scripts/windows/test.bat + # BENCHMARKING: + # name: BENCHMARKING + # if: github.repository == 'php/php-src' || github.event_name == 'pull_request' + # runs-on: ubuntu-22.04 + # steps: + # - name: git checkout + # uses: actions/checkout@v5 + # with: + # fetch-depth: 0 + # - name: apt + # run: | + # set -x + # sudo apt-get update + # sudo apt-get install \ + # bison \ + # libgmp-dev \ + # libonig-dev \ + # libsqlite3-dev \ + # openssl \ + # re2c \ + # valgrind + # - name: ccache + # uses: hendrikmuhs/ccache-action@v1.2 + # with: + # key: "${{github.job}}-${{hashFiles('main/php_version.h')}}" + # append-timestamp: false + # save: ${{ github.event_name != 'pull_request' }} + # - name: ./configure + # run: | + # set -x + # ./buildconf --force + # ./configure \ + # --disable-debug \ + # --enable-mbstring \ + # --enable-opcache \ + # --enable-option-checking=fatal \ + # --enable-sockets \ + # --enable-werror \ + # --prefix=/usr \ + # --with-config-file-scan-dir=/etc/php.d \ + # --with-gmp \ + # --with-mysqli=mysqlnd \ + # --with-openssl \ + # --with-pdo-sqlite \ + # --with-valgrind + # - name: make + # run: make -j$(/usr/bin/nproc) >/dev/null + # - name: make install + # run: | + # set -x + # sudo make install + # sudo mkdir -p /etc/php.d + # sudo chmod 777 /etc/php.d + # echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini + # echo zend_extension=opcache.so >> /etc/php.d/opcache.ini + # echo opcache.enable=1 >> /etc/php.d/opcache.ini + # echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini + # - name: Setup + # run: | + # git config --global user.name "Benchmark" + # git config --global user.email "benchmark@php.net" + # sudo service mysql start + # mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS wordpress" + # mysql -uroot -proot -e "CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'wordpress'; FLUSH PRIVILEGES;" + # mysql -uroot -proot -e "GRANT ALL PRIVILEGES ON *.* TO 'wordpress'@'localhost' WITH GRANT OPTION;" + # - name: git checkout benchmarking-data + # uses: actions/checkout@v5 + # with: + # repository: php/benchmarking-data + # ssh-key: ${{ secrets.BENCHMARKING_DATA_DEPLOY_KEY }} + # path: benchmark/repos/data + # - name: Benchmark + # run: php benchmark/benchmark.php true + # - name: Store result + # if: github.event_name == 'push' + # run: | + # set -x + # cd benchmark/repos/data + # git pull --autostash + # if [ -e ".git/MERGE_HEAD" ]; then + # echo "Merging, can't proceed" + # exit 1 + # fi + # git add . + # if git diff --cached --quiet; then + # exit 0 + # fi + # git commit -m "Add result for ${{ github.repository }}@${{ github.sha }}" + # git push + # - name: Show diff + # if: github.event_name == 'pull_request' + # run: |- + # set -x + # php benchmark/generate_diff.php \ + # ${{ github.sha }} \ + # $(git merge-base ${{ github.event.pull_request.base.sha }} ${{ github.sha }}) \ + # > $GITHUB_STEP_SUMMARY + # FREEBSD: + # if: github.repository == 'php/php-src' || github.event_name == 'pull_request' + # name: FREEBSD + # runs-on: ubuntu-latest + # timeout-minutes: 50 + # steps: + # - name: git checkout + # uses: actions/checkout@v5 + # - name: FreeBSD + # uses: ./.github/actions/freebsd diff --git a/ext/standard/tests/dns/.gitignore b/ext/standard/tests/dns/.gitignore new file mode 100644 index 0000000000000..8733cb86a6a92 --- /dev/null +++ b/ext/standard/tests/dns/.gitignore @@ -0,0 +1,2 @@ +managed-keys.* +named.conf diff --git a/ext/standard/tests/dns/bind-start.sh b/ext/standard/tests/dns/bind-start.sh new file mode 100755 index 0000000000000..fbf5785a116e7 --- /dev/null +++ b/ext/standard/tests/dns/bind-start.sh @@ -0,0 +1,395 @@ +#!/usr/bin/bash + +set -euo pipefail + +# Resolve script location +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ZONES_DIR="$SCRIPT_DIR/zones" +NAMED_CONF_TEMPLATE="$SCRIPT_DIR/named.conf.in" +NAMED_CONF="$SCRIPT_DIR/named.conf" +PID_FILE="$ZONES_DIR/named.pid" +LOG_FILE="$SCRIPT_DIR/named.log" + +# Debug: show current user and permissions +echo "Debug: Current user: $(whoami)" +echo "Debug: Current UID: $(id -u)" +echo "Debug: Script dir: $SCRIPT_DIR" +echo "Debug: Zones dir: $ZONES_DIR" + +# Default mode: background +FOREGROUND=false +if [[ "${1:-}" == "-f" ]]; then + FOREGROUND=true +fi + +# Ensure zones directory exists +if [ ! -d "$ZONES_DIR" ]; then + echo "Zone directory $ZONES_DIR not found." + exit 1 +fi + +# Ensure template exists +if [ ! -f "$NAMED_CONF_TEMPLATE" ]; then + echo "Template file $NAMED_CONF_TEMPLATE not found." + exit 1 +fi + +# Generate named.conf from template +echo "Generating $NAMED_CONF from $NAMED_CONF_TEMPLATE" + +# Check if 127.0.0.1 is available and decide on listen address +echo "Debug: Testing network connectivity for BIND address selection..." + +IPV4_OK=false +IPV6_OK=false + +# Test IPv4 connectivity +if ping -c 1 127.0.0.1 >/dev/null 2>&1; then + IPV4_OK=true + echo "Debug: IPv4 (127.0.0.1) is reachable" +else + echo "Debug: IPv4 (127.0.0.1) is NOT reachable" +fi + +# Test IPv6 connectivity +if command -v ping6 >/dev/null 2>&1; then + if ping6 -c 1 ::1 >/dev/null 2>&1; then + IPV6_OK=true + echo "Debug: IPv6 (::1) is reachable" + fi +else + if ping -6 -c 1 ::1 >/dev/null 2>&1; then + IPV6_OK=true + echo "Debug: IPv6 (::1) is reachable via ping -6" + fi +fi + +if ! $IPV6_OK; then + echo "Debug: IPv6 (::1) is NOT reachable" +fi + +# Choose the listen address +if $IPV4_OK; then + LISTEN_ADDRESS="127.0.0.1" + echo "Debug: Using IPv4 (127.0.0.1) for BIND" +elif $IPV6_OK; then + LISTEN_ADDRESS="::1" + echo "Debug: Using IPv6 (::1) for BIND" +else + echo "Debug: Neither 127.0.0.1 nor ::1 is available!" + echo "Debug: Falling back to 127.0.0.1 anyway" + LISTEN_ADDRESS="127.0.0.1" +fi + +sed -e "s|@ZONES_DIR@|$ZONES_DIR|g" \ + -e "s|@PID_FILE@|$PID_FILE|g" \ + -e "s|@SCRIPT_DIR@|$SCRIPT_DIR|g" \ + -e "s|@LISTEN_ADDRESS@|$LISTEN_ADDRESS|g" \ + "$NAMED_CONF_TEMPLATE" > "$NAMED_CONF" + +# Ensure the generated config file is readable +chmod 644 "$NAMED_CONF" + +# Debug: Check if the file is actually readable +echo "Debug: Testing config file readability:" +if [[ -r "$NAMED_CONF" ]]; then + echo "Debug: Config file is readable" +else + echo "Debug: Config file is NOT readable" + ls -la "$NAMED_CONF" + exit 1 +fi + +# Ensure the generated config file is readable +chmod 644 "$NAMED_CONF" + +# Determine the best user to run BIND as (do this early) +echo "Debug: Determining user for BIND..." + +# Get the owner of the script directory +SCRIPT_OWNER=$(stat -c '%U' "$SCRIPT_DIR") +SCRIPT_GROUP=$(stat -c '%G' "$SCRIPT_DIR") + +echo "Debug: Script directory owned by: $SCRIPT_OWNER:$SCRIPT_GROUP" +echo "Debug: Current user: $(whoami)" + +# Use the script owner if it's not root, otherwise use current user +if [[ "$SCRIPT_OWNER" != "root" ]] && id "$SCRIPT_OWNER" >/dev/null 2>&1; then + BIND_USER="$SCRIPT_OWNER" + echo "Debug: Will run BIND as script owner: $BIND_USER" +else + BIND_USER="$(whoami)" + echo "Debug: Will run BIND as current user: $BIND_USER" +fi + +# Handle AppArmor if present +if [[ -f /etc/apparmor.d/usr.sbin.named ]]; then + echo "Debug: AppArmor profile detected, disabling it..." + + # Install apparmor-utils if not present + if ! command -v aa-disable >/dev/null 2>&1; then + echo "Debug: Installing apparmor-utils..." + apt-get update -qq + apt-get install -y apparmor-utils + fi + + # Disable the profile + aa-disable /usr/sbin/named 2>/dev/null || echo "Failed to disable AppArmor profile" + + echo "Debug: AppArmor status:" + aa-status 2>/dev/null | grep named || echo "No named profile found (good!)" +else + echo "Debug: No AppArmor profile found for named" +fi + +# Enhanced AppArmor handling +if [[ -f /etc/apparmor.d/usr.sbin.named ]]; then + echo "Debug: AppArmor profile detected, attempting comprehensive bypass..." + + # Install apparmor-utils if not present + if ! command -v aa-complain >/dev/null 2>&1; then + echo "Debug: Installing apparmor-utils..." + apt-get update -qq + apt-get install -y apparmor-utils + fi + + # Check initial status + echo "Debug: Initial AppArmor status for named:" + aa-status 2>/dev/null | grep named || echo "No named profile in initial aa-status" + + # Try complain mode first + echo "Debug: Setting to complain mode..." + aa-complain /usr/sbin/named 2>/dev/null || echo "Failed to set AppArmor to complain mode" + + # Check what mode it's actually in + echo "Debug: AppArmor profile mode after complain:" + cat /sys/kernel/security/apparmor/profiles 2>/dev/null | grep named || echo "No named in profiles" + + # Try to completely disable it + echo "Debug: Attempting to disable AppArmor profile completely..." + aa-disable /usr/sbin/named 2>/dev/null || echo "Failed to disable AppArmor profile" + + # Alternative disable method + echo "Debug: Trying alternative disable method..." + ln -sf /etc/apparmor.d/usr.sbin.named /etc/apparmor.d/disable/ 2>/dev/null || echo "Symlink method failed" + + # Unload from kernel + if command -v apparmor_parser >/dev/null 2>&1; then + echo "Debug: Unloading profile from kernel..." + apparmor_parser -R /etc/apparmor.d/usr.sbin.named 2>/dev/null || echo "Failed to unload profile" + fi + + # Final status check + echo "Debug: Final AppArmor status:" + aa-status 2>/dev/null | grep named || echo "No named profile found (good!)" + +elif [ -d /etc/apparmor.d/ ]; then + echo "Debug: AppArmor directory exists but no named profile found:" + ls /etc/apparmor.d/ | grep -i named || echo "No named-related profiles" +else + echo "Debug: No AppArmor directory found" +fi + +echo "Debug: Generated named.conf contents:" +cat "$NAMED_CONF" + +# Clean up any leftover journal or PID files +rm -f "$ZONES_DIR"/*.jnl "$PID_FILE" + +# Print what we're doing +echo "Starting BIND from $SCRIPT_DIR" + +if $FOREGROUND; then + echo "(running in foreground)" + echo "Debug: About to exec: named -c $NAMED_CONF -p 53 -u $BIND_USER -g -d 1" + exec named -c "$NAMED_CONF" -p 53 -u "$BIND_USER" -g -d 1 +else + echo "(running in background)" + echo "Debug: About to run: named -c $NAMED_CONF -p 53 -u $BIND_USER" + + # Test configuration first + echo "Debug: Testing BIND configuration..." + if named-checkconf "$NAMED_CONF"; then + echo "Debug: Configuration check passed" + else + echo "Debug: Configuration check failed" + exit 1 + fi + + # Check if zone files exist + echo "Debug: Checking zone files..." + if [[ -f "$ZONES_DIR/basic.dnstest.php.net.zone" ]]; then + echo "Debug: Zone file exists" + echo "Debug: Zone file contents:" + cat "$ZONES_DIR/basic.dnstest.php.net.zone" + else + echo "Debug: Zone file missing: $ZONES_DIR/basic.dnstest.php.net.zone" + ls -la "$ZONES_DIR/" + exit 1 + fi + + # Set up permissions for the chosen user + echo "Debug: Setting up permissions for user: $BIND_USER..." + + # Ensure files are readable by the chosen user + chmod 644 "$NAMED_CONF" "$ZONES_DIR"/*.zone + chmod 755 "$SCRIPT_DIR" "$ZONES_DIR" + + echo "Debug: File permissions after setup:" + ls -la "$NAMED_CONF" "$ZONES_DIR"/*.zone + + echo "Debug: Directory permissions:" + ls -ld "$SCRIPT_DIR" "$ZONES_DIR" + + # Test if the chosen user can actually read the config file + echo "Debug: Testing $BIND_USER access to config file:" + if [[ "$BIND_USER" == "$(whoami)" ]]; then + # Same user, test directly + if test -r "$NAMED_CONF"; then + echo "Debug: $BIND_USER CAN read config file" + else + echo "Debug: $BIND_USER CANNOT read config file" + fi + else + # Different user, test with sudo + if sudo -u "$BIND_USER" test -r "$NAMED_CONF" 2>/dev/null; then + echo "Debug: $BIND_USER CAN read config file" + else + echo "Debug: $BIND_USER CANNOT read config file" + echo "Debug: Checking what $BIND_USER sees:" + sudo -u "$BIND_USER" ls -la "$NAMED_CONF" 2>&1 || echo "$BIND_USER cannot stat the file" + fi + fi + + echo "Debug: File permissions after setup:" + ls -la "$NAMED_CONF" "$ZONES_DIR"/*.zone + + echo "Debug: Directory permissions:" + ls -ld "$SCRIPT_DIR" "$ZONES_DIR" + + # Test if the chosen user can actually read the config file + echo "Debug: Testing $BIND_USER access to config file:" + if [[ "$BIND_USER" == "$(whoami)" ]]; then + # Same user, test directly + if test -r "$NAMED_CONF"; then + echo "Debug: $BIND_USER CAN read config file" + else + echo "Debug: $BIND_USER CANNOT read config file" + fi + else + # Different user, test with sudo + if sudo -u "$BIND_USER" test -r "$NAMED_CONF" 2>/dev/null; then + echo "Debug: $BIND_USER CAN read config file" + else + echo "Debug: $BIND_USER CANNOT read config file" + echo "Debug: Checking what $BIND_USER sees:" + sudo -u "$BIND_USER" ls -la "$NAMED_CONF" 2>&1 || echo "$BIND_USER cannot stat the file" + fi + fi + + # Check IPv4/IPv6 configuration with fallbacks + echo "Debug: Network configuration check:" + echo "Debug: localhost resolution:" + getent hosts localhost 2>/dev/null || echo "localhost not found in hosts" + + echo "Debug: 127.0.0.1 resolution:" + getent hosts 127.0.0.1 2>/dev/null || echo "127.0.0.1 not found" + + echo "Debug: Available IP addresses:" + if command -v ip >/dev/null 2>&1; then + ip addr show lo 2>/dev/null || echo "Failed to show loopback interface with ip" + else + ifconfig lo 2>/dev/null || echo "Failed to show loopback interface with ifconfig" + fi + + echo "Debug: Can we reach 127.0.0.1?" + ping -c 1 127.0.0.1 >/dev/null 2>&1 && echo "127.0.0.1 is reachable" || echo "127.0.0.1 is NOT reachable" + + echo "Debug: Can we reach ::1?" + if command -v ping6 >/dev/null 2>&1; then + ping6 -c 1 ::1 >/dev/null 2>&1 && echo "::1 is reachable" || echo "::1 is NOT reachable" + else + ping -6 -c 1 ::1 >/dev/null 2>&1 && echo "::1 is reachable (via ping -6)" || echo "::1 is NOT reachable" + fi + + # Check what's listening on port 53 + echo "Debug: Processes listening on port 53:" + if command -v ss >/dev/null 2>&1; then + ss -tulpn 2>/dev/null | grep ':53' || echo "Debug: No processes found on port 53 (ss)" + else + netstat -tulpn 2>/dev/null | grep ':53' || echo "Debug: No processes found on port 53 (netstat)" + fi + + echo "Debug: systemd-resolved status:" + systemctl is-active systemd-resolved 2>/dev/null || echo "systemd-resolved not active" + + # Monitor AppArmor denials in background + echo "Debug: Starting AppArmor denial monitoring..." + (timeout 15 tail -f /var/log/syslog 2>/dev/null | grep "apparmor.*DENIED" | head -10 &) || echo "Could not start syslog monitoring" + + # Use the determined user + echo "Debug: Using determined user: $BIND_USER" + + # Run named and capture both stdout and stderr separately + echo "Debug: Starting named as user: $BIND_USER..." + if named -c "$NAMED_CONF" -p 53 -u "$BIND_USER" > "$LOG_FILE" 2>&1; then + echo "Debug: named command succeeded" + else + NAMED_EXIT_CODE=$? + echo "Debug: named command failed with exit code: $NAMED_EXIT_CODE" + echo "Debug: Log file contents:" + cat "$LOG_FILE" 2>/dev/null || echo "No log file found" + + # Show any AppArmor denials + echo "Debug: Checking for AppArmor denials:" + grep "apparmor.*DENIED.*named" /var/log/syslog 2>/dev/null | tail -10 || echo "No AppArmor denials found in syslog" + + # Show general AppArmor messages + echo "Debug: Recent AppArmor messages for named:" + grep "apparmor.*named" /var/log/syslog 2>/dev/null | tail -10 || echo "No AppArmor messages found" + + # Try to run named with more verbose output + echo "Debug: Trying to run named in foreground for better error output:" + timeout 5 named -c "$NAMED_CONF" -p 53 -u "$BIND_USER" -g -d 1 || echo "Foreground attempt timed out or failed" + + exit $NAMED_EXIT_CODE + fi + + # Wait for BIND to start with periodic checks + MAX_WAIT=20 # Maximum wait time in attempts (20 * 0.5s = 10s) + CHECK_INTERVAL=0.5 # Check every 500ms + ATTEMPTS=0 + + echo -n "Waiting for BIND to start" + + while [[ $ATTEMPTS -lt $MAX_WAIT ]]; do + if [[ -f "$PID_FILE" ]] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then + echo "" # New line after the dots + ELAPSED=$(echo "scale=1; $ATTEMPTS * $CHECK_INTERVAL" | bc 2>/dev/null || echo "${ATTEMPTS}") + echo "BIND started in background with PID $(cat "$PID_FILE") (took ~${ELAPSED}s)" + exit 0 + fi + + echo -n "." + sleep "$CHECK_INTERVAL" + ((ATTEMPTS++)) + done + + echo "" # New line after the dots + TOTAL_WAIT=$(echo "scale=1; $MAX_WAIT * $CHECK_INTERVAL" | bc 2>/dev/null || echo "${MAX_WAIT}") + echo "Failed to start BIND within ~${TOTAL_WAIT}s. See $LOG_FILE for details." + + # Show last few lines of log for debugging + if [[ -f "$LOG_FILE" ]]; then + echo "Last few lines from log:" + tail -5 "$LOG_FILE" + else + echo "No log file found at $LOG_FILE" + fi + + # Final AppArmor check + echo "Debug: Final AppArmor denial check:" + grep "apparmor.*DENIED.*named" /var/log/syslog 2>/dev/null | tail -5 || echo "No final AppArmor denials found" + + exit 1 +fi diff --git a/ext/standard/tests/dns/bind-stop.sh b/ext/standard/tests/dns/bind-stop.sh new file mode 100755 index 0000000000000..e871ae79f802f --- /dev/null +++ b/ext/standard/tests/dns/bind-stop.sh @@ -0,0 +1,25 @@ +#!/usr/bin/bash + +set -euo pipefail + +# Resolve script location +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ZONES_DIR="$SCRIPT_DIR/zones" +PID_FILE="$ZONES_DIR/named.pid" +NAMED_CONF="$SCRIPT_DIR/named.conf" + +if [ -f "$PID_FILE" ]; then + NAMED_PID=$(cat $PID_FILE) + if [ -n "$NAMED_PID" ]; then + echo "Stopping BIND running on pid $NAMED_PID" + kill $NAMED_PID + else + echo "BIND pid is empty" + fi +else + echo "BIND is not running" +fi + +if [ -f "$NAMED_CONF" ]; then + rm "$NAMED_CONF" +fi \ No newline at end of file diff --git a/ext/standard/tests/dns/dns_get_record_basic.phpt b/ext/standard/tests/dns/dns_get_record_basic.phpt new file mode 100644 index 0000000000000..986bb9789e1ae --- /dev/null +++ b/ext/standard/tests/dns/dns_get_record_basic.phpt @@ -0,0 +1,28 @@ +--TEST-- +dns_get_record() basic usage +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +WRONG +array(%d) { + [0]=> + array(%d) { + ["host"]=> + string(%d) "www.basic.dnstest.php.net" + ["class"]=> + string(2) "IN" + ["ttl"]=> + int(%d) + ["type"]=> + string(1) "A" + ["ip"]=> + string(%d) "192.0.2.1" + } +} diff --git a/ext/standard/tests/dns/named.conf.in b/ext/standard/tests/dns/named.conf.in new file mode 100644 index 0000000000000..b7849456b0c5d --- /dev/null +++ b/ext/standard/tests/dns/named.conf.in @@ -0,0 +1,12 @@ +options { + directory "@ZONES_DIR@"; + listen-on port 53 { 127.0.0.1; }; + allow-query { any; }; + pid-file "@PID_FILE@"; + recursion yes; +}; + +zone "basic.dnstest.php.net" { + type master; + file "basic.dnstest.php.net.zone"; +}; diff --git a/ext/standard/tests/dns/resolv-reset.sh b/ext/standard/tests/dns/resolv-reset.sh new file mode 100755 index 0000000000000..9a4ecfd34cbde --- /dev/null +++ b/ext/standard/tests/dns/resolv-reset.sh @@ -0,0 +1,16 @@ +#!/usr/bin/bash +set -euo pipefail + +echo "Current DNS configuration:" +resolvectl status | grep -E 'Link|Current DNS Server:|DNS Servers:' + +echo -e "\nResetting DNS configuration by restarting systemd-resolved..." +systemctl restart systemd-resolved.service + +# Give it a moment to fully restart +sleep 1 + +echo -e "\nUpdated DNS configuration:" +resolvectl status | grep -E 'Link|Current DNS Server:|DNS Servers:' + +echo -e "\nDNS configuration has been reset to original state." \ No newline at end of file diff --git a/ext/standard/tests/dns/resolv-setup.sh b/ext/standard/tests/dns/resolv-setup.sh new file mode 100755 index 0000000000000..71dc91ac5112c --- /dev/null +++ b/ext/standard/tests/dns/resolv-setup.sh @@ -0,0 +1,112 @@ +#!/usr/bin/bash +set -euo pipefail + +LOCAL_DNS="127.0.0.1" + +echo "Looking for a DNS-enabled network interface..." + +resolvectl status + +# Find the interface with DNS and DefaultRoute using grep +IFACE=$(resolvectl status | grep -B1 "Current Scopes: DNS" | grep "Link" | head -n1 | sed -E 's/Link [0-9]+ \(([^)]+)\)/\1/') + +if [[ -z "$IFACE" ]]; then + echo "Could not find a suitable interface with DNS configured." + exit 1 +fi + +echo "Using interface: $IFACE" + +# Check if NetworkManager is running +systemctl is-active NetworkManager || echo "NetworkManager disabled" + +# Check if systemd-networkd is running +systemctl is-active systemd-networkd || echo "systemd-networkd disabled" + +# Check what's managing your interface +networkctl status $IFACE + +# Check network configs +echo "Checking 10-netplan-eth0.network" +if [ -f /run/systemd/network/10-netplan-eth0.network ]; then + # Check if UseDNS is already configured + if ! grep -q "UseDNS=" /run/systemd/network/10-netplan-eth0.network; then + echo "Adding UseDNS=false to DHCP section" + + # Use sed to add UseDNS=false after the [DHCP] section header + sed -i '/^\[DHCP\]/a UseDNS=false' /run/systemd/network/10-netplan-eth0.network + + echo "Updated configuration:" + cat /run/systemd/network/10-netplan-eth0.network + + # Restart systemd-networkd + systemctl restart systemd-networkd + sleep 2 + else + echo "UseDNS already configured in the file" + grep "UseDNS" /run/systemd/network/10-netplan-eth0.network + fi + cat /run/systemd/network/10-netplan-eth0.network +elif [ -d /run/systemd/network/ ]; then + echo "ls -la /run/systemd/network/" + ls -la /run/systemd/network/ +else + echo "ls -la /run/systemd/" + ls -la /run/systemd/ +fi + +# Get current DNS server +echo "Current configuration:" +resolvectl status "$IFACE" | grep -E 'Current DNS Server:|DNS Servers:' + +# Store the original DNS server for fallback +ORIGINAL_DNS=$(resolvectl status "$IFACE" | grep "DNS Servers:" | sed 's/.*DNS Servers: //' | awk '{print $1}') +echo "Original DNS server: $ORIGINAL_DNS" + +echo "Setting DNS to $LOCAL_DNS for $IFACE (with fallback to $ORIGINAL_DNS)" + +# Reset interface configuration first +resolvectl revert "$IFACE" + +# Set DNS with local server FIRST (this makes it primary) +#resolvectl dns "$IFACE" "$LOCAL_DNS" "$ORIGINAL_DNS" +resolvectl dns "$IFACE" "$LOCAL_DNS" + +# Flush DNS cache +resolvectl flush-caches + +# Confirm setup +echo -e "\nUpdated configuration:" +resolvectl status + +# Check again what's managing your interface +networkctl status eth0 + +echo -e "\nTesting DNS resolution..." + +# Test if our local DNS is working +echo "Testing local BIND server directly:" +if dig @127.0.0.1 www.basic.dnstest.php.net A +short; then + echo "✓ Local BIND server is responding" +else + echo "✗ Local BIND server is not responding" + exit 1 +fi + +# Test system DNS resolution +echo -e "\nTesting system DNS resolution:" +if dig www.basic.dnstest.php.net A +short; then + echo "✓ System DNS resolution is working" +else + echo "✗ System DNS resolution failed" +fi + +# Test with nslookup as well +echo -e "\nTesting with nslookup:" +nslookup www.basic.dnstest.php.net || echo "nslookup failed" + +# Show which DNS server is actually being used +echo -e "\nFinal verification:" +resolvectl query www.basic.dnstest.php.net || echo "resolvectl query failed" + +echo -e "\nDNS configuration has been updated." diff --git a/ext/standard/tests/dns/skipif.inc b/ext/standard/tests/dns/skipif.inc new file mode 100644 index 0000000000000..732e971a56853 --- /dev/null +++ b/ext/standard/tests/dns/skipif.inc @@ -0,0 +1,13 @@ +