diff --git a/.gitattributes b/.gitattributes index 31c95b3..bbfa8e9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5,3 +5,4 @@ /tests export-ignore /phpunit.xml.dist export-ignore /phpcs.xml export-ignore +/util export-ignore diff --git a/.gitignore b/.gitignore index 0a59599..9d4b4c6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ -.idea/ *.phar .DS_Store +.idea/ +.vagrant/ build composer.lock docs diff --git a/.travis.yml b/.travis.yml index e1712a6..ee70a23 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,30 +1,35 @@ -language: php +# Fake out Travis CI, since PHP isn't supported when using their Docker services +language: python -php: - - 5.4 - - 5.5 - - 5.6 - - 7.0 - - hhvm +env: + - PHP_VERSION=5.4.45 ARCH=x86_64 + - PHP_VERSION=5.4.45 ARCH=mips + - PHP_VERSION=5.5.30 ARCH=x86_64 + - PHP_VERSION=5.5.30 ARCH=mips + - PHP_VERSION=5.6.14 ARCH=x86_64 + - PHP_VERSION=5.6.14 ARCH=mips + - PHP_VERSION=7.0.0RC4 ARCH=x86_64 + - PHP_VERSION=hhvm ARCH=x86_64 -sudo: false +sudo: required addons: apt: packages: - - uuid-dev + - php5-cli + - php5-curl + - qemu-user-static -before_script: - - travis_retry composer self-update - - travis_retry composer install --no-interaction --prefer-dist - - sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then printf "\n" | pecl install uuid; fi;' - - phpenv rehash +services: + - docker + +install: + - curl -sS https://getcomposer.org/installer | php + - travis_retry php composer.phar install --no-interaction --prefer-dist + - mkdir -p build/logs script: - - mkdir -p build/logs - - ./vendor/bin/parallel-lint src tests - - ./vendor/bin/phpunit --verbose - - ./vendor/bin/phpcs src --standard=psr2 -sp + - bash -ex ./util/run-tests.sh after_script: - php vendor/bin/coveralls diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d7390e2..0977458 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -60,3 +60,19 @@ The following tests must pass before we will accept a pull request. If any of th ./vendor/bin/phpunit --verbose ./vendor/bin/phpcs src --standard=psr2 -sp ``` + +### Locally Test With Emulated MIPS Architecture + +The following commands use [Vagrant](https://www.vagrantup.com/) to start an Ubuntu VM, install necessary dependencies, and then run the `util/run-tests.sh` script that will download a Docker image emulating the MIPS architecture. This is especially helpful for testing UUID generation in a big-endian environment. + +``` +vagrant init ubuntu/trusty64 +vagrant up +vagrant ssh +sudo apt-get install docker.io qemu-user-static php5-cli php5-curl +cd /vagrant +curl -sS https://getcomposer.org/installer | php +php composer.phar install --no-interaction --prefer-dist +mkdir -p build/logs +ARCH=mips PHP_VERSION=5.6.14 TRAVIS_BUILD_DIR=/vagrant ./util/run-tests.sh +``` diff --git a/tests/src/UuidTest.php b/tests/src/UuidTest.php index 7b0ae15..ea976cf 100644 --- a/tests/src/UuidTest.php +++ b/tests/src/UuidTest.php @@ -838,6 +838,7 @@ class UuidTest extends TestCase $previous = $factory->uuid4(); for ($i = 0; $i < 1000; $i ++) { + usleep(10); $uuid = $factory->uuid4(); $this->assertGreaterThan($previous->toString(), $uuid->toString()); diff --git a/util/build-docker-image.sh b/util/build-docker-image.sh new file mode 100755 index 0000000..5134e12 --- /dev/null +++ b/util/build-docker-image.sh @@ -0,0 +1,129 @@ +#!/bin/bash +### Build a Docker image for a target PHP version, CPU arch, and Debian version +# +# Based on: https://github.com/docker-32bit/debian +# +# See also: +# https://www.tomaz.me/2013/12/02/running-travis-ci-tests-on-arm.html +# +# Note: Building HHVM with this script is not supported. See instead: +# https://gist.github.com/ramsey/04cb15ff955d54484980 +# +# Recommended approach for running this script to build Docker images: +# +# vagrant init ubuntu/trusty64 +# vagrant up +# vagrant ssh +# sudo apt-get install docker.io +# sudo docker login +# cd /vagrant +# sudo ./util/build-docker-image.sh 5.6.14 mips mips wheezy +# +# or (for 64-bit, standard Debian): +# +# sudo ./util/build-docker-image.sh 5.6.14 x86_64 amd64 wheezy +# + +if [ $EUID -ne 0 ]; then + echo "This script must be run as root" 1>&2 + exit 1 +fi + +### settings +php_version=${1:-5.6.14} +qemu_arch=${2:-mips} +deb_arch=${3:-mips} +suite=${4:-wheezy} + +chroot_dir="/tmp/chroot/${qemu_arch}-${suite}-php-${php_version}" +apt_mirror="http://ftp.us.debian.org/debian" +docker_image="benramsey/ramsey-uuid:${qemu_arch}-${suite}-php-${php_version}" +tmp_package="/tmp/${qemu_arch}-${suite}-php-${php_version}.tgz" + +if [ `echo "${php_version}" | cut -c 1` = "7" ]; then + php_package="https://downloads.php.net/~ab/php-${php_version}.tar.bz2" +else + php_package="https://secure.php.net/distributions/php-${php_version}.tar.bz2" +fi + +### make sure that the required tools are installed +export DEBIAN_FRONTEND=noninteractive +apt-get update +apt-get install -y wget debootstrap qemu-user-static binfmt-support \ + docker.io php5-cli php5-curl + +### install a minbase system with debootstrap +debootstrap --foreign --arch=$deb_arch $suite $chroot_dir $apt_mirror +cp "/usr/bin/qemu-${qemu_arch}-static" $chroot_dir/usr/bin/ +chroot $chroot_dir ./debootstrap/debootstrap --second-stage + +### update the list of package sources +cat < $chroot_dir/etc/apt/sources.list +deb $apt_mirror $suite main contrib non-free +deb $apt_mirror $suite-updates main contrib non-free +deb http://security.debian.org/ $suite/updates main contrib non-free +EOF + +### upgrade packages +chroot $chroot_dir apt-get update -qq +chroot $chroot_dir apt-get upgrade -qq -y + +### locale configuration +chroot $chroot_dir apt-get install -qq -y debconf +chroot $chroot_dir bash -c 'echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen' +chroot $chroot_dir dpkg-reconfigure locales + +### install dependencies to build PHP +chroot $chroot_dir apt-get --allow-unauthenticated install -qq -y \ + autoconf build-essential libcurl3-openssl-dev libgmp-dev libmcrypt-dev \ + libreadline-dev libxml2-dev uuid-dev curl git + +### download, build, and install the PHP version needed for this chroot +mkdir -p $chroot_dir/php-src +cd $chroot_dir/php-src +wget $php_package +tar jxf "php-${php_version}.tar.bz2" +chroot $chroot_dir bash -c "cd /php-src/php-${php_version} && ./configure --disable-all --enable-bcmath --with-gmp --disable-cgi --enable-xml --enable-libxml --enable-dom --enable-filter --enable-ctype --enable-json --with-openssl --enable-phar --enable-hash --with-curl --enable-simplexml --enable-tokenizer --enable-xmlwriter --enable-zip" +chroot $chroot_dir bash -c "cd /php-src/php-${php_version} && make && make install" +chroot $chroot_dir cp "/php-src/php-${php_version}/php.ini-development" /usr/local/lib/php.ini + +### download, build, and install the PECL UUID extension +wget https://pecl.php.net/get/uuid-1.0.4.tgz +tar zxf uuid-1.0.4.tgz +chroot $chroot_dir bash -c "cd /php-src/uuid-1.0.4 && phpize && ./configure && make && make install" +chroot $chroot_dir bash -c 'printf "date.timezone=UTC\n" >> /usr/local/lib/php.ini' +chroot $chroot_dir bash -c 'printf "extension=uuid.so\n" >> /usr/local/lib/php.ini' + +if [ `echo "${php_version}" | cut -c 1` != "7" ]; then + ### download, build, and install Xdebug, if not PHP 7 + wget http://xdebug.org/files/xdebug-2.3.3.tgz + tar zxf xdebug-2.3.3.tgz + chroot $chroot_dir bash -c "cd /php-src/xdebug-2.3.3 && phpize && ./configure --enable-xdebug && make && make install" + chroot $chroot_dir bash -c "printf \"zend_extension=\$(php -r \"echo ini_get('extension_dir');\")/xdebug.so\n\" >> /usr/local/lib/php.ini" +fi + +### globally install Composer +chroot $chroot_dir bash -c "curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer" + +### cleanup +chroot $chroot_dir apt-get autoclean +chroot $chroot_dir apt-get clean +chroot $chroot_dir apt-get autoremove + +cd /tmp +rm -rf $chroot_dir/php-src + +### create a tar archive from the chroot directory +tar cfz $tmp_package -C $chroot_dir . + +### import this tar archive into a docker image: +cat $tmp_package | docker import - $docker_image + +### push image to Docker Hub +docker push $docker_image + +### cleanup +rm $tmp_package +rm -rf $chroot_dir + +echo "Done!" diff --git a/util/run-tests.sh b/util/run-tests.sh new file mode 100755 index 0000000..44edd04 --- /dev/null +++ b/util/run-tests.sh @@ -0,0 +1,42 @@ +#!/bin/bash +### Run tests based on CPU architecture +# +# Depending on the ARCH indicated for this test job, run the tests in a +# Docker container based on the PHP version for this job. +# + +if [ -z "${ARCH}" ]; then + echo "The ARCH environment variable must be provided" + exit 1 +fi + +if [ -z "${PHP_VERSION}" ]; then + echo "The PHP_VERSION environment variable must be provided" + exit 1 +fi + +if [ -z "${TRAVIS_BUILD_DIR}" ]; then + echo "The TRAVIS_BUILD_DIR environment variable must be provided" + exit 1 +fi + +if [ "${PHP_VERSION}" = "hhvm" ]; then + docker_tag="${ARCH}-trusty-php-${PHP_VERSION}" +else + docker_tag="${ARCH}-wheezy-php-${PHP_VERSION}" +fi + +declare -a commands +commands[0]="echo \"Environment: \$(uname -a)\"" +commands[1]="php --version" +commands[2]="cd ${TRAVIS_BUILD_DIR}" +commands[3]="./vendor/bin/parallel-lint src tests" +commands[4]="./vendor/bin/phpcs src --standard=psr2 -sp" +commands[5]="./vendor/bin/phpunit --verbose" + +printf -v command "%s && " "${commands[@]}" +command=${command::-4} + +sudo docker run -v "${TRAVIS_BUILD_DIR}":"${TRAVIS_BUILD_DIR}" \ + benramsey/ramsey-uuid:$docker_tag \ + bash -c "${command}"