summaryrefslogtreecommitdiff
path: root/azure
diff options
context:
space:
mode:
Diffstat (limited to 'azure')
-rw-r--r--azure/apt.yml42
-rw-r--r--azure/community_job.yml83
-rw-r--r--azure/configure.yml62
-rw-r--r--azure/coverage_job.yml45
-rw-r--r--azure/i386/apt.yml46
-rw-r--r--azure/i386/job.yml96
-rw-r--r--azure/i386/test.yml33
-rw-r--r--azure/install.yml11
-rw-r--r--azure/job.yml31
-rw-r--r--azure/lsan-suppressions.txt1
-rw-r--r--azure/macos/brew.yml43
-rw-r--r--azure/macos/job.yml87
-rw-r--r--azure/macos/test.yml29
-rw-r--r--azure/msan_job.yml79
-rwxr-xr-xazure/setup-slapd.sh169
-rw-r--r--azure/setup.yml13
-rw-r--r--azure/test.yml34
17 files changed, 904 insertions, 0 deletions
diff --git a/azure/apt.yml b/azure/apt.yml
new file mode 100644
index 0000000000..e8da9b001d
--- /dev/null
+++ b/azure/apt.yml
@@ -0,0 +1,42 @@
+parameters:
+ packages: ''
+
+steps:
+ - script: |
+ sudo apt-get update -y | true
+ sudo apt install bison \
+ re2c \
+ locales \
+ ldap-utils \
+ openssl \
+ slapd \
+ language-pack-de \
+ re2c \
+ libgmp-dev \
+ libicu-dev \
+ libtidy-dev \
+ libenchant-dev \
+ libaspell-dev \
+ libpspell-dev \
+ libsasl2-dev \
+ libxpm-dev \
+ libzip-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 \
+ postgresql \
+ postgresql-contrib \
+ llvm \
+ ${{ parameters.packages }}
+ displayName: 'APT'
diff --git a/azure/community_job.yml b/azure/community_job.yml
new file mode 100644
index 0000000000..87b06184ba
--- /dev/null
+++ b/azure/community_job.yml
@@ -0,0 +1,83 @@
+parameters:
+ configurationName: ''
+ configurationParameters: ''
+ timeoutInMinutes: 60
+
+# The purpose of the job is to test open-source community projects against an aggressive
+# debug build, that enables assertions, as well as the address and UB sanitizers. However,
+# we are only interested in finding assertion failures, segfaults and sanitizer violations,
+# and don't care about the actual test results, as there will commonly be failures for
+# pre-release versions of PHP.
+#
+# Because exit() in PHP results in an unclean shutdown, test runs are patching phpunit to
+# avoid the exit, which allows us to also check for memory leaks. Otherwise we use
+# USE_TRACKED_ALLOC=1 to avoid reporting of leaks that will be handled by ZMM.
+jobs:
+ - job: ${{ parameters.configurationName }}
+ timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
+ pool:
+ vmImage: 'ubuntu-18.04'
+ variables:
+ ubsan_options: 'print_stacktrace=1'
+ steps:
+ - template: apt.yml
+ - script: |
+ # Compile a newer version of curl, otherwise there will be an asan warning
+ # when running symfony tests.
+ wget https://curl.haxx.se/download/curl-7.65.3.tar.gz
+ tar xzf curl-7.65.3.tar.gz
+ cd curl-7.65.3/
+ ./configure
+ make -j2
+ sudo make install
+ displayName: 'Build Curl'
+ - template: configure.yml
+ parameters:
+ configurationParameters: ${{ parameters.configurationParameters }}
+ - script: make -j$(/usr/bin/nproc) >/dev/null
+ displayName: 'Make Build'
+ - script: |
+ sudo make install
+ sudo mkdir /etc/php.d
+ sudo chmod 777 /etc/php.d
+ echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini
+ echo pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/pdo_mysql.ini
+ # Run with opcache to also catch optimizer bugs.
+ echo zend_extension=opcache.so > /etc/php.d/opcache.ini
+ echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini
+ echo opcache.protect_memory=1 >> /etc/php.d/opcache.ini
+ displayName: 'Install Build'
+ - script: |
+ git clone https://github.com/laravel/framework.git --branch=master --depth=1
+ cd framework
+ php7.3 /usr/bin/composer install --no-progress
+ export USE_ZEND_ALLOC=0
+ sed -i 's/$exit = true/$exit = false/g' vendor/phpunit/phpunit/src/TextUI/Command.php
+ # Avoid test using exit(), which thus leaks.
+ # We can use USE_TRACKED_ALLOC=1 if more of these show up.
+ sed -i "s/function_exists('pcntl_fork')/false/" tests/Filesystem/FilesystemTest.php
+ php vendor/bin/phpunit
+ displayName: 'Test Laravel'
+ - script: |
+ git clone https://github.com/symfony/symfony.git --branch=master --depth=1
+ cd symfony
+ php7.3 /usr/bin/composer install --no-progress
+ php7.3 ./phpunit install
+ export USE_ZEND_ALLOC=0
+ export USE_TRACKED_ALLOC=1
+ export ASAN_OPTIONS=exitcode=139
+ php ./phpunit --exclude-group tty,benchmark,intl-data,transient
+ if [ $? -gt 128 ]; then
+ exit 1
+ fi
+ displayName: 'Test Symfony'
+ condition: or(succeeded(), failed())
+ - script: |
+ git clone https://github.com/amphp/amp.git --branch=master --depth=1
+ cd amp
+ php /usr/bin/composer install --no-progress --ignore-platform-reqs
+ export USE_ZEND_ALLOC=0
+ sed -i 's/$exit = true/$exit = false/g' vendor/phpunit/phpunit/src/TextUI/Command.php
+ php vendor/bin/phpunit
+ displayName: 'Test Amphp'
+ condition: or(succeeded(), failed())
diff --git a/azure/configure.yml b/azure/configure.yml
new file mode 100644
index 0000000000..1d3374bfa0
--- /dev/null
+++ b/azure/configure.yml
@@ -0,0 +1,62 @@
+parameters:
+ configurationParameters: ''
+
+steps:
+- script: |
+ ./buildconf --force
+ ./configure ${{ parameters.configurationParameters }} \
+ --enable-option-checking=fatal \
+ --prefix=/usr \
+ --enable-phpdbg \
+ --enable-fpm \
+ --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 \
+ --with-xmlrpc \
+ --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 \
+ --with-ldap \
+ --with-ldap-sasl \
+ --with-password-argon2 \
+ --with-mhash \
+ --with-sodium \
+ --enable-werror \
+ --with-config-file-path=/etc \
+ --with-config-file-scan-dir=/etc/php.d
+ displayName: 'Configure Build'
diff --git a/azure/coverage_job.yml b/azure/coverage_job.yml
new file mode 100644
index 0000000000..01bde10281
--- /dev/null
+++ b/azure/coverage_job.yml
@@ -0,0 +1,45 @@
+parameters:
+ configurationName: ''
+ configurationParameters: ''
+ runTestsParameters: ''
+ timeoutInMinutes: 60
+
+jobs:
+ - job: ${{ parameters.configurationName }}
+ timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
+ pool:
+ vmImage: 'ubuntu-18.04'
+ steps:
+ - template: apt.yml
+ - script: |
+ sudo -H pip install gcovr
+ displayName: 'Install gcovr'
+ - template: configure.yml
+ parameters:
+ configurationParameters: --enable-gcov ${{ parameters.configurationParameters }}
+ - script: make -j$(/usr/bin/nproc) >/dev/null
+ displayName: 'Make Build'
+ - template: install.yml
+ - template: setup.yml
+ - template: test.yml
+ parameters:
+ configurationName: ${{ parameters.configurationName }}
+ runTestsParameters: ${{ parameters.runTestsParameters }}
+ - template: test.yml
+ parameters:
+ configurationName: ${{ parameters.configurationName }}
+ runTestsName: 'OpCache'
+ runTestsParameters: >-
+ ${{ parameters.runTestsParameters }}
+ -d zend_extension=opcache.so
+ - script: |
+ make gcovr-xml
+ mv gcovr.xml coverage.xml
+ displayName: 'Generate ${{ parameters.configurationName }} Test Coverage'
+ condition: or(succeeded(), failed())
+ - task: PublishCodeCoverageResults@1
+ inputs:
+ codeCoverageTool: 'Cobertura'
+ summaryFileLocation: coverage.xml
+ displayName: 'Publish ${{ parameters.configurationName }} Test Coverage'
+ condition: or(succeeded(), failed())
diff --git a/azure/i386/apt.yml b/azure/i386/apt.yml
new file mode 100644
index 0000000000..4dd09423c9
--- /dev/null
+++ b/azure/i386/apt.yml
@@ -0,0 +1,46 @@
+parameters:
+ packages: ''
+
+steps:
+ - script: |
+ sudo dpkg --add-architecture i386
+ sudo apt-get update -y | true
+ sudo apt-get install -y gcc-multilib
+ sudo apt-get install -y g++-multilib
+ sudo apt-get purge -y libxml2 libsqlite3-0
+ # TODO: Reenable postgresql + postgresql-contrib packages once they work again.
+ sudo apt-get install -y bison \
+ re2c \
+ locales \
+ language-pack-de \
+ libglib2.0-dev:i386 \
+ libssl-dev:i386 \
+ zlib1g-dev:i386 \
+ libxml2-dev:i386 \
+ libgmp-dev:i386 \
+ libicu-dev:i386 \
+ libtidy-dev:i386 \
+ libenchant-dev:i386 \
+ libaspell-dev:i386 \
+ libpspell-dev:i386 \
+ libsasl2-dev:i386 \
+ libxpm-dev:i386 \
+ libjpeg-dev:i386 \
+ libpng-dev:i386 \
+ libzip-dev:i386 \
+ libbz2-dev:i386 \
+ libsqlite3-dev:i386 \
+ libwebp-dev:i386 \
+ libonig-dev:i386 \
+ libkrb5-dev:i386 \
+ libgssapi-krb5-2:i386 \
+ libcurl4-openssl-dev:i386 \
+ libxml2-dev:i386 \
+ libxslt1-dev:i386 \
+ libpq-dev:i386 \
+ libreadline-dev:i386 \
+ libffi-dev:i386 \
+ libfreetype6-dev:i386 \
+ libsodium-dev:i386 \
+ ${{ parameters.packages }}
+ displayName: 'APT'
diff --git a/azure/i386/job.yml b/azure/i386/job.yml
new file mode 100644
index 0000000000..83e8705f0f
--- /dev/null
+++ b/azure/i386/job.yml
@@ -0,0 +1,96 @@
+parameters:
+ configurationName: ''
+ configurationParameters: ''
+
+jobs:
+ - job: ${{ parameters.configurationName }}
+ pool:
+ vmImage: 'ubuntu-18.04'
+ steps:
+ - template: apt.yml
+ - script: |
+ ./buildconf --force
+ export CFLAGS=-m32
+ export CXXFLAGS=-m32
+ export LDFLAGS=-L/usr/lib/i386-linux-gnu
+ export PKG_CONFIG=/usr/bin/i686-linux-gnu-pkg-config
+ ./configure ${{ parameters.configurationParameters }} \
+ --enable-option-checking=fatal \
+ --prefix=/usr \
+ --enable-phpdbg \
+ --enable-fpm \
+ --enable-intl \
+ --with-pdo-mysql=mysqlnd \
+ --with-mysqli=mysqlnd \
+ --with-pgsql \
+ --with-pdo-pgsql \
+ --with-pdo-sqlite \
+ --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 \
+ --with-xmlrpc \
+ --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 \
+ --with-mhash \
+ --with-sodium \
+ --enable-werror \
+ --with-config-file-path=/etc \
+ --with-config-file-scan-dir=/etc/php.d
+ displayName: 'Configure Build'
+ - script: make -j$(/usr/bin/nproc) >/dev/null
+ displayName: 'Make Build'
+ - script: |
+ set -e
+ sudo make install
+ sudo mkdir /etc/php.d
+ sudo chmod 777 /etc/php.d
+ echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini
+ echo pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/pdo_mysql.ini
+ echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini
+ echo opcache.protect_memory=1 >> /etc/php.d/opcache.ini
+ displayName: 'Install Build'
+ - script: |
+ set -e
+ sudo service mysql start
+ mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test"
+ #sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"
+ #sudo -u postgres psql -c "CREATE DATABASE test;"
+ displayName: 'Setup'
+ - template: test.yml
+ parameters:
+ configurationName: ${{ parameters.configurationName }}
+ - template: test.yml
+ parameters:
+ configurationName: ${{ parameters.configurationName }}
+ runTestsName: 'OpCache'
+ runTestsParameters: -d zend_extension=opcache.so
diff --git a/azure/i386/test.yml b/azure/i386/test.yml
new file mode 100644
index 0000000000..1e2e1d6a1e
--- /dev/null
+++ b/azure/i386/test.yml
@@ -0,0 +1,33 @@
+parameters:
+ runTestsName: ''
+ runTestsParameters: ''
+
+steps:
+ - script: |
+ export MYSQL_TEST_USER=root
+ export MYSQL_TEST_PASSWD=root
+ export PDO_MYSQL_TEST_DSN="mysql:host=localhost;dbname=test"
+ export PDO_MYSQL_TEST_USER=root
+ export PDO_MYSQL_TEST_PASS=root
+ export TEST_PHP_JUNIT=junit.xml
+ export REPORT_EXIT_STATUS=no
+ export SKIP_IO_CAPTURE_TESTS=1
+ rm -rf junit.xml | true
+ php run-tests.php -P -q \
+ -j$(/usr/bin/nproc) \
+ -g FAIL,XFAIL,BORK,WARN,LEAK,XLEAK,SKIP \
+ --offline \
+ --show-diff \
+ --show-slow 1000 \
+ --set-timeout 120 \
+ ${{ parameters.runTestsParameters }}
+ displayName: 'Test ${{ parameters.configurationName }} ${{ parameters.runTestsName }}'
+ condition: or(succeeded(), failed())
+ - task: PublishTestResults@2
+ inputs:
+ testResultsFormat: 'JUnit'
+ testResultsFiles: junit.xml
+ testRunTitle: '${{ parameters.configurationName }} ${{ parameters.runTestsName }}'
+ failTaskOnFailedTests: true
+ displayName: 'Export ${{ parameters.configurationName }} ${{ parameters.runTestsName }} Results'
+ condition: or(succeeded(), failed())
diff --git a/azure/install.yml b/azure/install.yml
new file mode 100644
index 0000000000..3cd6122071
--- /dev/null
+++ b/azure/install.yml
@@ -0,0 +1,11 @@
+steps:
+ - script: |
+ set -e
+ sudo make install
+ sudo mkdir /etc/php.d
+ sudo chmod 777 /etc/php.d
+ echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini
+ echo pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/pdo_mysql.ini
+ echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini
+ echo opcache.protect_memory=1 >> /etc/php.d/opcache.ini
+ displayName: 'Install Build'
diff --git a/azure/job.yml b/azure/job.yml
new file mode 100644
index 0000000000..2893653b18
--- /dev/null
+++ b/azure/job.yml
@@ -0,0 +1,31 @@
+parameters:
+ configurationName: ''
+ configurationParameters: ''
+ runTestsParameters: ''
+ timeoutInMinutes: 60
+
+jobs:
+ - job: ${{ parameters.configurationName }}
+ timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
+ pool:
+ vmImage: 'ubuntu-18.04'
+ steps:
+ - template: apt.yml
+ - template: configure.yml
+ parameters:
+ configurationParameters: ${{ parameters.configurationParameters }}
+ - script: make -j$(/usr/bin/nproc) >/dev/null
+ displayName: 'Make Build'
+ - template: install.yml
+ - template: setup.yml
+ - template: test.yml
+ parameters:
+ configurationName: ${{ parameters.configurationName }}
+ runTestsParameters: ${{ parameters.runTestsParameters }}
+ - template: test.yml
+ parameters:
+ configurationName: ${{ parameters.configurationName }}
+ runTestsName: 'OpCache'
+ runTestsParameters: >-
+ ${{ parameters.runTestsParameters }}
+ -d zend_extension=opcache.so
diff --git a/azure/lsan-suppressions.txt b/azure/lsan-suppressions.txt
new file mode 100644
index 0000000000..5c2ee76e46
--- /dev/null
+++ b/azure/lsan-suppressions.txt
@@ -0,0 +1 @@
+leak:acommon::DictInfoList::elements
diff --git a/azure/macos/brew.yml b/azure/macos/brew.yml
new file mode 100644
index 0000000000..fb8b9ace2d
--- /dev/null
+++ b/azure/macos/brew.yml
@@ -0,0 +1,43 @@
+parameters:
+ packages: ''
+
+steps:
+ - script: brew update
+ displayName: 'Update Homebrew'
+ - script: |
+ brew install pkg-config \
+ autoconf \
+ bison
+ displayName: 'Install Build Tools'
+ - script: |
+ brew install openssl@1.1 \
+ krb5 \
+ bzip2 \
+ enchant \
+ libffi \
+ libpng \
+ webp \
+ freetype \
+ intltool \
+ icu4c \
+ libiconv \
+ zlib \
+ t1lib \
+ gd \
+ gmp \
+ tidyp \
+ libxml2 \
+ libxslt \
+ postgresql
+ # Make sure we don't get broken libzip 1.7.0
+ brew upgrade libzip
+ brew link icu4c gettext --force
+ displayName: 'Install Build Dependencies'
+ - script: |
+ wget https://github.com/skvadrik/re2c/releases/download/2.0.1/re2c-2.0.1.tar.xz
+ tar -xf re2c-2.0.1.tar.xz
+ cd re2c-2.0.1
+ ./configure
+ make -j$(sysctl -n hw.ncpu)
+ make install
+ displayName: 'Build re2c'
diff --git a/azure/macos/job.yml b/azure/macos/job.yml
new file mode 100644
index 0000000000..4b979d41a8
--- /dev/null
+++ b/azure/macos/job.yml
@@ -0,0 +1,87 @@
+parameters:
+ configurationName: ''
+ configurationParameters: ''
+
+jobs:
+ - job: ${{ parameters.configurationName }}
+ pool:
+ vmImage: 'macOS-10.14'
+ steps:
+ - template: brew.yml
+ - script: |
+ export PATH="/usr/local/opt/bison/bin:$PATH"
+ export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/openssl@1.1/lib/pkgconfig"
+ export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/krb5/lib/pkgconfig"
+ export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/libffi/lib/pkgconfig"
+ export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/libxml2/lib/pkgconfig"
+ export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/libxslt/lib/pkgconfig"
+ export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/zlib/lib/pkgconfig"
+ export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/icu4c/lib/pkgconfig"
+ ./buildconf --force
+ ./configure ${{ parameters.configurationParameters }} \
+ --enable-option-checking=fatal \
+ --prefix=/usr/local \
+ --disable-phpdbg \
+ --enable-fpm \
+ --with-pdo-mysql=mysqlnd \
+ --with-mysqli=mysqlnd \
+ --with-pgsql=/usr/local/opt/libpq \
+ --with-pdo-pgsql=/usr/local/opt/libpq \
+ --with-pdo-sqlite \
+ --without-pear \
+ --enable-gd \
+ --with-jpeg \
+ --with-webp \
+ --with-freetype \
+ --enable-exif \
+ --with-zip \
+ --with-zlib \
+ --enable-soap \
+ --enable-xmlreader \
+ --with-xsl \
+ --with-tidy=/usr/local/opt/tidyp \
+ --with-xmlrpc \
+ --with-libxml \
+ --enable-sysvsem \
+ --enable-sysvshm \
+ --enable-shmop \
+ --enable-pcntl \
+ --with-readline=/usr/local/opt/readline \
+ --enable-mbstring \
+ --with-curl \
+ --with-gettext=/usr/local/opt/gettext \
+ --enable-sockets \
+ --with-bz2=/usr/local/opt/bzip2 \
+ --with-openssl \
+ --with-gmp=/usr/local/opt/gmp \
+ --with-iconv=/usr/local/opt/libiconv \
+ --enable-bcmath \
+ --enable-calendar \
+ --enable-ftp \
+ --with-pspell=/usr/local/opt/aspell \
+ --with-kerberos \
+ --enable-sysvmsg \
+ --with-ffi \
+ --enable-zend-test \
+ --enable-intl \
+ --with-mhash \
+ --with-sodium \
+ --enable-werror \
+ --with-config-file-path=/etc \
+ --with-config-file-scan-dir=/etc/php.d
+ displayName: 'Configure Build'
+ - script: |
+ export PATH="/usr/local/opt/bison/bin:$PATH"
+ make -j$(sysctl -n hw.ncpu) >/dev/null
+ displayName: 'Make Build'
+ - script: |
+ sudo make install
+ displayName: 'Install Build'
+ - template: test.yml
+ parameters:
+ configurationName: ${{ parameters.configurationName }}
+ - template: test.yml
+ parameters:
+ configurationName: ${{ parameters.configurationName }}
+ runTestsName: 'OpCache'
+ runTestsParameters: -d zend_extension=opcache.so -d opcache.enable_cli=1 -d opcache.protect_memory=1
diff --git a/azure/macos/test.yml b/azure/macos/test.yml
new file mode 100644
index 0000000000..f139e53e40
--- /dev/null
+++ b/azure/macos/test.yml
@@ -0,0 +1,29 @@
+parameters:
+ runTestsName: ''
+ runTestsParameters: ''
+
+steps:
+ - script: |
+ export TEST_PHP_JUNIT=junit.xml
+ export REPORT_EXIT_STATUS=no
+ export SKIP_IO_CAPTURE_TESTS=1
+ export CI_NO_IPV6=1
+ rm -rf junit.xml | true
+ /usr/local/bin/php run-tests.php -P -q \
+ -j$(sysctl -n hw.ncpu) \
+ -g FAIL,XFAIL,BORK,WARN,LEAK,XLEAK,SKIP \
+ --offline \
+ --show-diff \
+ --show-slow 1000 \
+ --set-timeout 120 \
+ ${{ parameters.runTestsParameters }}
+ displayName: 'Test ${{ parameters.configurationName }} ${{ parameters.runTestsName }}'
+ condition: or(succeeded(), failed())
+ - task: PublishTestResults@2
+ inputs:
+ testResultsFormat: 'JUnit'
+ testResultsFiles: junit.xml
+ testRunTitle: '${{ parameters.configurationName }} ${{ parameters.runTestsName }}'
+ failTaskOnFailedTests: true
+ displayName: 'Export ${{ parameters.configurationName }} ${{ parameters.runTestsName }} Results'
+ condition: or(succeeded(), failed())
diff --git a/azure/msan_job.yml b/azure/msan_job.yml
new file mode 100644
index 0000000000..3c6cb4ca09
--- /dev/null
+++ b/azure/msan_job.yml
@@ -0,0 +1,79 @@
+parameters:
+ configurationName: ''
+ configurationParameters: ''
+ runTestsParameters: ''
+ timeoutInMinutes: 60
+
+jobs:
+ - job: ${{ parameters.configurationName }}
+ timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
+ pool:
+ vmImage: 'ubuntu-18.04'
+ steps:
+ - template: apt.yml
+ - script: |
+ export CC=clang
+ export CXX=clang++
+ export CFLAGS="-fsanitize=memory -DZEND_TRACK_ARENA_ALLOC"
+ export LDFLAGS="-fsanitize=memory"
+ ./buildconf --force
+ # msan requires all used libraries to be instrumented,
+ # so we should avoiding linking against anything but libc here
+ ./configure ${{ parameters.configurationParameters }} \
+ --enable-option-checking=fatal \
+ --prefix=/usr \
+ --without-sqlite3 \
+ --without-pdo-sqlite \
+ --without-libxml \
+ --disable-dom \
+ --disable-simplexml \
+ --disable-xml \
+ --disable-xmlreader \
+ --disable-xmlwriter \
+ --without-pcre-jit \
+ --enable-phpdbg \
+ --enable-fpm \
+ --with-pdo-mysql=mysqlnd \
+ --with-mysqli=mysqlnd \
+ --disable-mysqlnd-compression-support \
+ --without-pear \
+ --enable-exif \
+ --enable-sysvsem \
+ --enable-sysvshm \
+ --enable-shmop \
+ --enable-pcntl \
+ --enable-mbstring \
+ --disable-mbregex \
+ --enable-sockets \
+ --enable-bcmath \
+ --enable-calendar \
+ --enable-ftp \
+ --enable-zend-test \
+ --enable-werror \
+ --with-config-file-path=/etc \
+ --with-config-file-scan-dir=/etc/php.d
+ displayName: 'Configure Build'
+ - script: make -j$(/usr/bin/nproc) >/dev/null
+ displayName: 'Make Build'
+ - script: |
+ sudo make install
+ sudo mkdir /etc/php.d
+ sudo chmod 777 /etc/php.d
+ echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini
+ echo pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/pdo_mysql.ini
+ displayName: 'Install Build'
+ - script: |
+ sudo service mysql start
+ mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test"
+ displayName: 'Setup'
+ - template: test.yml
+ parameters:
+ configurationName: ${{ parameters.configurationName }}
+ runTestsParameters: ${{ parameters.runTestsParameters }}
+ - template: test.yml
+ parameters:
+ configurationName: ${{ parameters.configurationName }}
+ runTestsName: 'OpCache'
+ runTestsParameters: >-
+ ${{ parameters.runTestsParameters }}
+ -d zend_extension=opcache.so -d opcache.enable_cli=1
diff --git a/azure/setup-slapd.sh b/azure/setup-slapd.sh
new file mode 100755
index 0000000000..72a509f7e0
--- /dev/null
+++ b/azure/setup-slapd.sh
@@ -0,0 +1,169 @@
+#!/bin/sh
+set -ev
+
+# Create TLS certificate
+sudo mkdir -p /etc/ldap/ssl
+
+alt_names() {
+ (
+ (
+ (hostname && hostname -a && hostname -A && hostname -f) |
+ xargs -n 1 |
+ sort -u |
+ sed -e 's/\(\S\+\)/DNS:\1/g'
+ ) && (
+ (hostname -i && hostname -I && echo "127.0.0.1 ::1") |
+ xargs -n 1 |
+ sort -u |
+ sed -e 's/\(\S\+\)/IP:\1/g'
+ )
+ ) | paste -d, -s
+}
+
+sudo openssl req -newkey rsa:4096 -x509 -nodes -days 3650 \
+ -out /etc/ldap/ssl/server.crt -keyout /etc/ldap/ssl/server.key \
+ -subj "/C=US/ST=Arizona/L=Localhost/O=localhost/CN=localhost" \
+ -addext "subjectAltName = `alt_names`"
+
+sudo chown -R openldap:openldap /etc/ldap/ssl
+
+# Display the TLS certificate (should be world readable)
+openssl x509 -noout -text -in /etc/ldap/ssl/server.crt
+
+# Point to the certificate generated
+if ! grep -q 'TLS_CACERT \/etc\/ldap\/ssl\/server.crt' /etc/ldap/ldap.conf; then
+ sudo sed -e 's|^\s*TLS_CACERT|# TLS_CACERT|' -i /etc/ldap/ldap.conf
+ echo 'TLS_CACERT /etc/ldap/ssl/server.crt' | sudo tee -a /etc/ldap/ldap.conf
+fi
+
+# Configure LDAP protocols to serve.
+sudo sed -e 's|^\s*SLAPD_SERVICES\s*=.*$|SLAPD_SERVICES="ldap:/// ldaps:/// ldapi:///"|' -i /etc/default/slapd
+
+# Configure LDAP database.
+DBDN=`sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config '(&(olcRootDN=*)(olcSuffix=*))' dn | grep -i '^dn:' | sed -e 's/^dn:\s*//'`;
+
+sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/ppolicy.ldif
+
+sudo service slapd restart
+
+sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// << EOF
+dn: $DBDN
+changetype: modify
+replace: olcSuffix
+olcSuffix: dc=my-domain,dc=com
+-
+replace: olcRootDN
+olcRootDN: cn=Manager,dc=my-domain,dc=com
+-
+replace: olcRootPW
+olcRootPW: secret
+
+dn: cn=config
+changetype: modify
+add: olcTLSCACertificateFile
+olcTLSCACertificateFile: /etc/ldap/ssl/server.crt
+-
+add: olcTLSCertificateFile
+olcTLSCertificateFile: /etc/ldap/ssl/server.crt
+-
+add: olcTLSCertificateKeyFile
+olcTLSCertificateKeyFile: /etc/ldap/ssl/server.key
+-
+add: olcTLSVerifyClient
+olcTLSVerifyClient: never
+-
+add: olcAuthzRegexp
+olcAuthzRegexp: uid=usera,cn=digest-md5,cn=auth cn=usera,dc=my-domain,dc=com
+-
+replace: olcLogLevel
+olcLogLevel: -1
+
+dn: cn=module{0},cn=config
+changetype: modify
+add: olcModuleLoad
+olcModuleLoad: sssvlv
+-
+add: olcModuleLoad
+olcModuleLoad: ppolicy
+-
+add: olcModuleLoad
+olcModuleLoad: dds
+EOF
+
+sudo service slapd restart
+
+sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// << EOF
+dn: olcOverlay=sssvlv,$DBDN
+objectClass: olcOverlayConfig
+objectClass: olcSssVlvConfig
+olcOverlay: sssvlv
+olcSssVlvMax: 10
+olcSssVlvMaxKeys: 5
+
+dn: olcOverlay=ppolicy,$DBDN
+objectClass: olcOverlayConfig
+objectClass: olcPPolicyConfig
+olcOverlay: ppolicy
+### This would clutter our DIT and make tests to fail, while ppolicy does not
+### seem to work as we expect (it does not seem to provide expected controls)
+## olcPPolicyDefault: cn=default,ou=pwpolicies,dc=my-domain,dc=com
+## olcPPolicyHashCleartext: FALSE
+## olcPPolicyUseLockout: TRUE
+
+dn: olcOverlay=dds,$DBDN
+objectClass: olcOverlayConfig
+objectClass: olcDdsConfig
+olcOverlay: dds
+EOF
+
+sudo service slapd restart
+
+sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// << EOF
+dn: $DBDN
+changetype: modify
+add: olcDbIndex
+olcDbIndex: entryExpireTimestamp eq
+EOF
+
+sudo service slapd restart
+
+ldapadd -H ldapi:/// -D cn=Manager,dc=my-domain,dc=com -w secret <<EOF
+dn: dc=my-domain,dc=com
+objectClass: top
+objectClass: organization
+objectClass: dcObject
+dc: my-domain
+o: php ldap tests
+
+### This would clutter our DIT and make tests to fail, while ppolicy does not
+### seem to work as we expect (it does not seem to provide expected controls)
+## dn: ou=pwpolicies,dc=my-domain,dc=com
+## objectClass: top
+## objectClass: organizationalUnit
+## ou: pwpolicies
+##
+## dn: cn=default,ou=pwpolicies,dc=my-domain,dc=com
+## objectClass: top
+## objectClass: person
+## objectClass: pwdPolicy
+## cn: default
+## sn: default
+## pwdAttribute: userPassword
+## pwdMaxAge: 2592000
+## pwdExpireWarning: 3600
+## #pwdInHistory: 0
+## pwdCheckQuality: 0
+## pwdMaxFailure: 5
+## pwdLockout: TRUE
+## #pwdLockoutDuration: 0
+## #pwdGraceAuthNLimit: 0
+## #pwdFailureCountInterval: 0
+## pwdMustChange: FALSE
+## pwdMinLength: 3
+## pwdAllowUserChange: TRUE
+## pwdSafeModify: FALSE
+EOF
+
+# Verify TLS connection
+
+ldapsearch -d 255 -H ldaps://localhost -D cn=Manager,dc=my-domain,dc=com -w secret -s base -b dc=my-domain,dc=com 'objectclass=*'
diff --git a/azure/setup.yml b/azure/setup.yml
new file mode 100644
index 0000000000..523bb3b401
--- /dev/null
+++ b/azure/setup.yml
@@ -0,0 +1,13 @@
+steps:
+ - script: |
+ set -e
+ sudo service mysql start
+ sudo service postgresql start
+ sudo service slapd start
+ mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test"
+ sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"
+ sudo -u postgres psql -c "CREATE DATABASE test;"
+ displayName: 'Setup'
+ - script: ./azure/setup-slapd.sh
+ displayName: 'Configure slapd'
+
diff --git a/azure/test.yml b/azure/test.yml
new file mode 100644
index 0000000000..4a1f97b734
--- /dev/null
+++ b/azure/test.yml
@@ -0,0 +1,34 @@
+parameters:
+ runTestsName: ''
+ runTestsParameters: ''
+
+steps:
+ - script: |
+ export MYSQL_TEST_USER=root
+ export MYSQL_TEST_PASSWD=root
+ export PDO_MYSQL_TEST_DSN="mysql:host=localhost;dbname=test"
+ export PDO_MYSQL_TEST_USER=root
+ export PDO_MYSQL_TEST_PASS=root
+ export TEST_PHP_JUNIT=junit.xml
+ export REPORT_EXIT_STATUS=no
+ export SKIP_IO_CAPTURE_TESTS=1
+ export MSAN_SYMBOLIZER_PATH=/usr/lib/llvm-6.0/bin/llvm-symbolizer
+ rm -rf junit.xml | true
+ php run-tests.php -P -q \
+ -j$(/usr/bin/nproc) \
+ -g FAIL,XFAIL,BORK,WARN,LEAK,XLEAK,SKIP \
+ --offline \
+ --show-diff \
+ --show-slow 1000 \
+ --set-timeout 120 \
+ ${{ parameters.runTestsParameters }}
+ displayName: 'Test ${{ parameters.configurationName }} ${{ parameters.runTestsName }}'
+ condition: or(succeeded(), failed())
+ - task: PublishTestResults@2
+ inputs:
+ testResultsFormat: 'JUnit'
+ testResultsFiles: junit.xml
+ testRunTitle: '${{ parameters.configurationName }} ${{ parameters.runTestsName }}'
+ failTaskOnFailedTests: true
+ displayName: 'Export ${{ parameters.configurationName }} ${{ parameters.runTestsName }} Results'
+ condition: or(succeeded(), failed())