1
0
mirror of https://github.com/danog/dns.git synced 2024-11-26 20:14:51 +01:00

Tests, Travis and Cache implementations

- Add tests
 - Configure repo for use with Travis
 - Add some more Cache implementations
This commit is contained in:
Danack 2014-07-19 14:37:48 +01:00 committed by Chris Wright
parent 10bd03789c
commit a50369e71e
17 changed files with 1754 additions and 117 deletions

14
.travis.yml Normal file
View File

@ -0,0 +1,14 @@
language: php
git:
submodules: false
php:
- 5.5
- 5.4
before_script:
- composer install
script: php ./vendor/bin/phpunit --configuration test/phpunit.xml --coverage-text

View File

@ -2,3 +2,6 @@ Addr
====
Asynchronous DNS resolver using [Alert](https://github.com/rdlowrey/Alert).
[![Build Status](https://travis-ci.org/Danack/Addr.svg?branch=AddingTestsAndActualCaches)](https://travis-ci.org/Danack/Addr)

View File

@ -16,9 +16,16 @@
"rdlowrey/alert": "~0.8.1",
"daverandom/libdns": "~0.2.1"
},
"require-dev": {
"mockery/mockery": ">=0.9.1",
"rdlowrey/auryn": ">=0.13.0",
"predis/predis": "dev-v0.9/phpdoc-method-tags as v0.8.4",
"phpunit/phpunit": "~4.1.0"
},
"autoload": {
"psr-4": {
"Addr\\": "lib/Addr/"
"Addr\\": "lib/Addr/",
"AddrCache\\": "lib/AddrCache/"
}
}
}

970
composer.lock generated Normal file
View File

@ -0,0 +1,970 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
],
"hash": "6ac53a76066ea6f5b5a4b6621ca23adb",
"packages": [
{
"name": "daverandom/libdns",
"version": "v0.2.1",
"source": {
"type": "git",
"url": "https://github.com/DaveRandom/LibDNS.git",
"reference": "f94f92f3fa8b2776ff2593c87d93d87480efeb73"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/DaveRandom/LibDNS/zipball/f94f92f3fa8b2776ff2593c87d93d87480efeb73",
"reference": "f94f92f3fa8b2776ff2593c87d93d87480efeb73",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"type": "library",
"autoload": {
"psr-0": {
"LibDNS": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "DNS protocol implementation written in pure PHP",
"keywords": [
"dns"
],
"time": "2013-11-28 15:57:15"
},
{
"name": "rdlowrey/alert",
"version": "v0.8.1",
"source": {
"type": "git",
"url": "https://github.com/rdlowrey/alert.git",
"reference": "a09cc62f81d8950e05e6c715668be3cb2a07d716"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rdlowrey/alert/zipball/a09cc62f81d8950e05e6c715668be3cb2a07d716",
"reference": "a09cc62f81d8950e05e6c715668be3cb2a07d716",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"type": "library",
"autoload": {
"files": [
"src/bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Daniel Lowrey",
"email": "rdlowrey@php.net",
"role": "Creator / Lead Developer"
}
],
"description": "Event loops for event-driven/async PHP",
"homepage": "https://github.com/rdlowrey/alert",
"keywords": [
"async",
"events",
"libevent",
"non-blocking"
],
"time": "2014-06-11 14:09:10"
}
],
"packages-dev": [
{
"name": "mockery/mockery",
"version": "0.9.1",
"source": {
"type": "git",
"url": "https://github.com/padraic/mockery.git",
"reference": "17f63ee40ed14a8afb7ba1f0ae15cc4491d719d1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/padraic/mockery/zipball/17f63ee40ed14a8afb7ba1f0ae15cc4491d719d1",
"reference": "17f63ee40ed14a8afb7ba1f0ae15cc4491d719d1",
"shasum": ""
},
"require": {
"lib-pcre": ">=7.0",
"php": ">=5.3.2"
},
"require-dev": {
"hamcrest/hamcrest-php": "~1.1",
"phpunit/phpunit": "~4.0",
"satooshi/php-coveralls": "~0.7@dev"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.9.x-dev"
}
},
"autoload": {
"psr-0": {
"Mockery": "library/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Pádraic Brady",
"email": "padraic.brady@gmail.com",
"homepage": "http://blog.astrumfutura.com"
},
{
"name": "Dave Marshall",
"email": "dave.marshall@atstsolutions.co.uk",
"homepage": "http://davedevelopment.co.uk"
}
],
"description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succint API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.",
"homepage": "http://github.com/padraic/mockery",
"keywords": [
"BDD",
"TDD",
"library",
"mock",
"mock objects",
"mockery",
"stub",
"test",
"test double",
"testing"
],
"time": "2014-05-02 12:16:45"
},
{
"name": "phpunit/php-code-coverage",
"version": "2.0.9",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "ed8ac99ce38c3fd134128c898f7ca74665abef7f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ed8ac99ce38c3fd134128c898f7ca74665abef7f",
"reference": "ed8ac99ce38c3fd134128c898f7ca74665abef7f",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"phpunit/php-file-iterator": "~1.3.1",
"phpunit/php-text-template": "~1.2.0",
"phpunit/php-token-stream": "~1.2.2",
"sebastian/environment": "~1.0.0",
"sebastian/version": "~1.0.3"
},
"require-dev": {
"ext-xdebug": ">=2.1.4",
"phpunit/phpunit": "~4.0.14"
},
"suggest": {
"ext-dom": "*",
"ext-xdebug": ">=2.2.1",
"ext-xmlwriter": "*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
"homepage": "https://github.com/sebastianbergmann/php-code-coverage",
"keywords": [
"coverage",
"testing",
"xunit"
],
"time": "2014-06-29 08:14:40"
},
{
"name": "phpunit/php-file-iterator",
"version": "1.3.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
"reference": "acd690379117b042d1c8af1fafd61bde001bf6bb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb",
"reference": "acd690379117b042d1c8af1fafd61bde001bf6bb",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"autoload": {
"classmap": [
"File/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "FilterIterator implementation that filters files based on a list of suffixes.",
"homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
"keywords": [
"filesystem",
"iterator"
],
"time": "2013-10-10 15:34:57"
},
{
"name": "phpunit/php-text-template",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-text-template.git",
"reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
"reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"autoload": {
"classmap": [
"Text/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Simple template engine.",
"homepage": "https://github.com/sebastianbergmann/php-text-template/",
"keywords": [
"template"
],
"time": "2014-01-30 17:20:04"
},
{
"name": "phpunit/php-timer",
"version": "1.0.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-timer.git",
"reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
"reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"autoload": {
"classmap": [
"PHP/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Utility class for timing",
"homepage": "https://github.com/sebastianbergmann/php-timer/",
"keywords": [
"timer"
],
"time": "2013-08-02 07:42:54"
},
{
"name": "phpunit/php-token-stream",
"version": "1.2.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
"reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/ad4e1e23ae01b483c16f600ff1bebec184588e32",
"reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2-dev"
}
},
"autoload": {
"classmap": [
"PHP/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Wrapper around PHP's tokenizer extension.",
"homepage": "https://github.com/sebastianbergmann/php-token-stream/",
"keywords": [
"tokenizer"
],
"time": "2014-03-03 05:10:30"
},
{
"name": "phpunit/phpunit",
"version": "4.1.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "a71c4842c5fb836d8b200624583b859ec34e8a26"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a71c4842c5fb836d8b200624583b859ec34e8a26",
"reference": "a71c4842c5fb836d8b200624583b859ec34e8a26",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-json": "*",
"ext-pcre": "*",
"ext-reflection": "*",
"ext-spl": "*",
"php": ">=5.3.3",
"phpunit/php-code-coverage": "~2.0",
"phpunit/php-file-iterator": "~1.3.1",
"phpunit/php-text-template": "~1.2",
"phpunit/php-timer": "~1.0.2",
"phpunit/phpunit-mock-objects": "~2.1",
"sebastian/comparator": "~1.0",
"sebastian/diff": "~1.1",
"sebastian/environment": "~1.0",
"sebastian/exporter": "~1.0",
"sebastian/version": "~1.0",
"symfony/yaml": "~2.0"
},
"suggest": {
"phpunit/php-invoker": "~1.1"
},
"bin": [
"phpunit"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.1.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
"",
"../../symfony/yaml/"
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"description": "The PHP Unit Testing framework.",
"homepage": "http://www.phpunit.de/",
"keywords": [
"phpunit",
"testing",
"xunit"
],
"time": "2014-07-18 07:15:58"
},
{
"name": "phpunit/phpunit-mock-objects",
"version": "2.1.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
"reference": "7878b9c41edb3afab92b85edf5f0981014a2713a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/7878b9c41edb3afab92b85edf5f0981014a2713a",
"reference": "7878b9c41edb3afab92b85edf5f0981014a2713a",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"phpunit/php-text-template": "~1.2"
},
"require-dev": {
"phpunit/phpunit": "~4.1"
},
"suggest": {
"ext-soap": "*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.1.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Mock Object library for PHPUnit",
"homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
"keywords": [
"mock",
"xunit"
],
"time": "2014-06-12 07:22:15"
},
{
"name": "predis/predis",
"version": "dev-v0.9/phpdoc-method-tags",
"source": {
"type": "git",
"url": "https://github.com/nrk/predis.git",
"reference": "6741b788cc2c8b37bd62c6ed5d38a671940993c3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nrk/predis/zipball/6741b788cc2c8b37bd62c6ed5d38a671940993c3",
"reference": "6741b788cc2c8b37bd62c6ed5d38a671940993c3",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
},
"suggest": {
"ext-curl": "Allows access to Webdis when paired with phpiredis",
"ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol"
},
"type": "library",
"autoload": {
"psr-0": {
"Predis": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Daniele Alessandri",
"email": "suppakilla@gmail.com",
"homepage": "http://clorophilla.net"
}
],
"description": "Flexible and feature-complete PHP client library for Redis",
"homepage": "http://github.com/nrk/predis",
"keywords": [
"nosql",
"predis",
"redis"
],
"time": "2013-12-21 17:28:51"
},
{
"name": "rdlowrey/auryn",
"version": "v0.13.0",
"source": {
"type": "git",
"url": "https://github.com/rdlowrey/Auryn.git",
"reference": "c83b741ccddf3b8e91f02dbdc5b0eeecbf20f09f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rdlowrey/Auryn/zipball/c83b741ccddf3b8e91f02dbdc5b0eeecbf20f09f",
"reference": "c83b741ccddf3b8e91f02dbdc5b0eeecbf20f09f",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"autoload": {
"files": [
"src/bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Levi Morrison",
"email": "levim@php.net",
"homepage": "http://morrisonlevi.github.com/",
"role": "Developer"
},
{
"name": "Daniel Lowrey",
"email": "rdlowrey@gmail.com",
"role": "Creator / Lead Developer"
},
{
"name": "Dan Ackroyd",
"email": "Danack@basereality.com",
"homepage": "http://www.basereality.com",
"role": "Developer"
}
],
"description": "Auryn is a dependency injector for bootstrapping object-oriented PHP applications.",
"homepage": "https://github.com/rdlowrey/Auryn",
"keywords": [
"dependency injection",
"dic",
"ioc"
],
"time": "2014-04-01 12:48:07"
},
{
"name": "sebastian/comparator",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2",
"reference": "f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"sebastian/diff": "~1.1",
"sebastian/exporter": "~1.0"
},
"require-dev": {
"phpunit/phpunit": "~4.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
},
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
},
{
"name": "Volker Dusch",
"email": "github@wallbash.com"
},
{
"name": "Bernhard Schussek",
"email": "bschussek@2bepublished.at"
}
],
"description": "Provides the functionality to compare PHP values for equality",
"homepage": "http://www.github.com/sebastianbergmann/comparator",
"keywords": [
"comparator",
"compare",
"equality"
],
"time": "2014-05-02 07:05:58"
},
{
"name": "sebastian/diff",
"version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
"reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d",
"reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
},
{
"name": "Kore Nordmann",
"email": "mail@kore-nordmann.de"
}
],
"description": "Diff implementation",
"homepage": "http://www.github.com/sebastianbergmann/diff",
"keywords": [
"diff"
],
"time": "2013-08-03 16:46:33"
},
{
"name": "sebastian/environment",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/environment.git",
"reference": "79517609ec01139cd7e9fded0dd7ce08c952ef6a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/79517609ec01139cd7e9fded0dd7ce08c952ef6a",
"reference": "79517609ec01139cd7e9fded0dd7ce08c952ef6a",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "4.0.*@dev"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"description": "Provides functionality to handle HHVM/PHP environments",
"homepage": "http://www.github.com/sebastianbergmann/environment",
"keywords": [
"Xdebug",
"environment",
"hhvm"
],
"time": "2014-02-18 16:17:19"
},
{
"name": "sebastian/exporter",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
"reference": "1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529",
"reference": "1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "4.0.*@dev"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
},
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
},
{
"name": "Volker Dusch",
"email": "github@wallbash.com"
},
{
"name": "Adam Harvey",
"email": "aharvey@php.net",
"role": "Lead"
},
{
"name": "Bernhard Schussek",
"email": "bschussek@2bepublished.at"
}
],
"description": "Provides the functionality to export PHP variables for visualization",
"homepage": "http://www.github.com/sebastianbergmann/exporter",
"keywords": [
"export",
"exporter"
],
"time": "2014-02-16 08:26:31"
},
{
"name": "sebastian/version",
"version": "1.0.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/version.git",
"reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/version/zipball/b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43",
"reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43",
"shasum": ""
},
"type": "library",
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
"homepage": "https://github.com/sebastianbergmann/version",
"time": "2014-03-07 15:35:33"
},
{
"name": "symfony/yaml",
"version": "v2.5.2",
"target-dir": "Symfony/Component/Yaml",
"source": {
"type": "git",
"url": "https://github.com/symfony/Yaml.git",
"reference": "f868ecdbcc0276b6158dfbf08b9e98ce07f014e1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Yaml/zipball/f868ecdbcc0276b6158dfbf08b9e98ce07f014e1",
"reference": "f868ecdbcc0276b6158dfbf08b9e98ce07f014e1",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.5-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Yaml\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Yaml Component",
"homepage": "http://symfony.com",
"time": "2014-07-09 09:05:48"
}
],
"aliases": [
{
"alias": "v0.8.4",
"alias_normalized": "0.8.4.0",
"version": "dev-v0.9/phpdoc-method-tags",
"package": "predis/predis"
}
],
"minimum-stability": "stable",
"stability-flags": {
"predis/predis": 20
},
"platform": {
"php": ">=5.4.0"
},
"platform-dev": [
]
}

View File

@ -1,35 +0,0 @@
<?php
namespace Addr;
/**
* Interface for record caches
*
* @package Addr
*/
interface Cache
{
/**
* Look up a name in the cache
*
* @param string $name Name to query
* @param int $type AddressModes::INET4_ADDR or AddressModes::INET6_ADDR
* @param callable $callback Function to receive the result
*/
public function resolve($name, $type, callable $callback);
/**
* Store an entry in the cache
*
* @param string $name Name to query
* @param string $addr IP address that $name maps to
* @param int $type AddressModes::INET4_ADDR or AddressModes::INET6_ADDR
* @param int $ttl Time the record should live, in seconds
*/
public function store($name, $addr, $type, $ttl);
/**
* Remove all expired records from the cache
*/
public function collectGarbage();
}

View File

@ -22,7 +22,7 @@ class Client
private $responseInterpreter;
/**
* @var Cache
* @var \AddrCache\Cache
*/
private $cache;
@ -72,7 +72,7 @@ class Client
* @param Reactor $reactor
* @param RequestBuilder $requestBuilder
* @param ResponseInterpreter $responseInterpreter
* @param Cache $cache
* @param \AddrCache\Cache $cache
* @param string $serverAddress
* @param int $serverPort
* @param int $requestTimeout
@ -82,7 +82,7 @@ class Client
Reactor $reactor,
RequestBuilder $requestBuilder,
ResponseInterpreter $responseInterpreter,
Cache $cache = null,
\AddrCache\Cache $cache = null,
$serverAddress = null,
$serverPort = null,
$requestTimeout = null
@ -243,10 +243,7 @@ class Client
$this->redirectPendingLookup($id, $addr);
}
} else if ($addr !== null) {
if ($this->cache) {
$this->cache->store($name, $addr, $type, $ttl);
}
$this->store($name, $addr, $type, $ttl);
$this->completeRequest($request, $addr, $type);
} else {
foreach ($request['lookups'] as $id => $lookup) {
@ -255,6 +252,28 @@ class Client
}
}
/**
* Generates the cache key used to store the result for hostname
* and type.
* @param $name
* @param $type
* @return string
*/
function generateCacheKey($name, $type) {
return 'Name:'.$name.',Type:'.$type;
}
/**
* @param $name
* @param $addr
* @param $type
* @param $ttl
*/
public function store($name, $addr, $type, $ttl) {
$key = $this->generateCacheKey($name, $type);
$this->cache->store($key, $addr, $ttl);
}
/**
* Call a response callback with the result
*
@ -300,19 +319,17 @@ class Client
$name = $this->pendingLookups[$id]['name'];
$type = array_shift($this->pendingLookups[$id]['requests']);
if ($this->cache) {
$this->cache->resolve($name, $type, function($addr) use ($id, $name, $type) {
if ($addr !== null) {
$this->completePendingLookup($id, $addr, $type);
} else {
$this->dispatchRequest($id, $name, $type);
}
});
$key = $this->generateCacheKey($name, $type);
list($cacheHit, $addr) = $this->cache->get($key);
if ($cacheHit === true) {
$this->completePendingLookup($id, $addr, $type);
} else {
$this->dispatchRequest($id, $name, $type);
}
}
/**
* Send a request to the server
*

View File

@ -1,62 +0,0 @@
<?php
namespace Addr;
class MemoryCache implements Cache
{
/**
* Mapped names stored in the cache
*
* @var array
*/
private $data = [
AddressModes::INET4_ADDR => [],
AddressModes::INET6_ADDR => [],
];
/**
* Look up an entry in the cache
*
* @param string $name
* @param int $type
* @param callable $callback
*/
public function resolve($name, $type, callable $callback)
{
if (!isset($this->data[$type][$name]) || $this->data[$type][$name][1] < time()) {
unset($this->data[$type][$name]);
$callback(null);
} else {
$callback($this->data[$type][$name][0]);
}
}
/**
* Store an entry in the cache
*
* @param string $name
* @param string $addr
* @param int $type
* @param int $ttl
*/
public function store($name, $addr, $type, $ttl)
{
$this->data[$type][$name] = [$addr, time() + $ttl];
}
/**
* Remove expired records from the cache
*/
public function collectGarbage()
{
$now = time();
foreach ([AddressModes::INET4_ADDR, AddressModes::INET6_ADDR] as $type) {
while (list($name, $data) = each($this->data[$type])) {
if ($data[1] < $now) {
unset($this->data[$type][$name]);
}
}
}
}
}

View File

@ -17,7 +17,7 @@ class ResolverFactory
* @param string $serverAddr
* @param int $serverPort
* @param int $requestTimeout
* @param Cache $cache
* @param \AddrCache\Cache $cache
* @param string $hostsFilePath
* @return Resolver
*/
@ -26,11 +26,11 @@ class ResolverFactory
$serverAddr = null,
$serverPort = null,
$requestTimeout = null,
Cache $cache = null,
\AddrCache\Cache $cache = null,
$hostsFilePath = null
) {
$nameValidator = new NameValidator;
$cache = $cache ?: new MemoryCache;
$cache = $cache ?: new \AddrCache\MemoryCache;
$client = new Client(
$reactor,

View File

@ -0,0 +1,55 @@
<?php
namespace AddrCache;
class APCCache implements \AddrCache\Cache {
/**
* @param string $prefix A prefix to prepend to all keys.
*/
function __construct($prefix = 'AddrCache\Cache\APCCache') {
$this->prefix = $prefix;
}
/**
* Attempt to retrieve a value from the cache
*
* Returns an array [$cacheHit, $value]
* [true, $valueFromCache] - if it existed in the cache
* [false, null] - if it didn't already exist in the cache
*
* @param $key
* @return array
*/
public function get($key) {
$key = $this->prefix.$key;
$value = apc_fetch($key, $success);
if ($success) {
return [true, $value];
}
return [false, null];
}
/**
* Stores a value in the cache. Overwrites the previous value if there was one.
*
* @param $key
* @param $value
* @param null $ttl
*/
public function store($key, $value, $ttl = null) {
$key = $this->prefix.$key;
apc_store($key, $value, $ttl);
}
/**
* Deletes an entry from the cache.
* @param $key
*/
public function delete($key) {
$key = $this->prefix.$key;
apc_delete($key);
}
}

34
lib/AddrCache/Cache.php Normal file
View File

@ -0,0 +1,34 @@
<?php
namespace AddrCache;
interface Cache {
/**
* Attempt to retrieve a value from the cache
*
* Returns an array [$cacheHit, $value]
* [true, $valueFromCache] - if it existed in the cache
* [false, null] - if it didn't already exist in the cache
*
* @param $key
* @return array
*/
public function get($key);
/**
* Stores a value in the cache. Overwrites the previous value if there was one.
*
* @param $key
* @param $value
* @param null $ttl
*/
public function store($key, $value, $ttl = null);
/**
* Deletes an entry from the cache.
* @param $key
*/
public function delete($key);
}

View File

@ -0,0 +1,75 @@
<?php
namespace AddrCache;
class MemoryCache implements \AddrCache\Cache {
const MAX_TTL = 31536000;//1 year
private $valueAndTTLArray = [];
/**
* Attempt to retrieve a value from the cache
*
* Returns an array [$cacheHit, $value]
* [true, $valueFromCache] - if it existed in the cache
* [false, null] - if it didn't already exist in the cache
*
* @param $key
* @return array
*/
public function get($key) {
if (array_key_exists($key, $this->valueAndTTLArray) == false) {
return [false, null];
}
list($value, $expireTime) = $this->valueAndTTLArray[$key];
if ($expireTime <= time()) {
return [false, null]; //It's already expired, so don't return cached value;
}
return [true, $value];
}
/**
* Stores a value in the cache. Overwrites the previous value if there was one.
*
* @param $key
* @param $value
* @param null $ttl
*/
public function store($key, $value, $ttl = null) {
if ($ttl === null) {
$ttl = self::MAX_TTL;
}
$this->valueAndTTLArray[$key] = [$value, time() + $ttl];
}
/**
* Deletes an entry from the cache.
* @param $key
*/
public function delete($key) {
unset($this->valueAndTTLArray[$key]);
}
/**
* Remove expired records from the cache
*/
public function collectGarbage()
{
$now = time();
foreach ($this->valueAndTTLArray as $key => $valueAndTTL) {
if ($valueAndTTL[1] <= $now) {
unset($this->valueAndTTLArray);
}
}
}
}

View File

@ -0,0 +1,89 @@
<?php
namespace AddrCache;
use Predis\Client as RedisClient;
class RedisCache implements \AddrCache\Cache {
/**
* @var RedisClient
*/
private $redisClient;
/**
* Lua script to get a value, and flag whether it was cache hit or miss.
* Don't delete the "== 1" - it's important in Lua
*/
const getLuaScript = <<< END
if redis.call("exists", KEYS[1]) == 1
then
return {1, redis.call("get",KEYS[1])}
else
return {0, 0}
end
END;
/**
* @param RedisClient $redisClient
* @param string $prefixKey A prefix to prepend to all keys. This can also be
* set via the redis client, in which case you may wish to pass an empty string
* as $prefixKey
*/
function __construct(RedisClient $redisClient, $prefixKey = 'AddrCache\Cache\RedisCache') {
$this->redisClient = $redisClient;
$this->prefix = $prefixKey;
}
/**
* Stores a value in the cache. Overwrites the previous value if there was one.
*
* @param $key
* @param $value
* @param null $ttl
*/
public function store($key, $value, $ttl = null) {
$key = $this->prefix.$key;
$ttl = intval($ttl);
if ($ttl > 0) {
$this->redisClient->set($key, $value, 'EX', $ttl);
}
else {
$this->redisClient->set($key, $value);
}
}
/**
* Attempt to retrieve a value from the cache
*
* Returns an array [$cacheHit, $value]
* [true, $valueFromCache] - if it existed in the cache
* [false, null] - if it didn't already exist in the cache
*
* @param $key
* @return array
*/
public function get($key) {
$key = $this->prefix.$key;
list($wasHit, $value) = $this->redisClient->eval(self::getLuaScript, 1, $key);
if ($wasHit) {
return [true, $value];
}
return [false, null];
}
/**
* @param $key
*/
public function delete($key) {
$key = $this->prefix.$key;
$this->redisClient->del([$key]);
}
}

116
test/AddrTest/AddrTest.php Normal file
View File

@ -0,0 +1,116 @@
<?php
namespace AddrTest;
use Addr\ResolverFactory,
Alert\ReactorFactory;
class AddrTest extends \PHPUnit_Framework_TestCase {
static private $redisEnabled = true;
static private $redisParameters = array(
'connection_timeout' => 2,
'read_write_timeout' => 2,
);
public static function setUpBeforeClass() {
try {
$predisClient = new \Predis\Client(self::$redisParameters, []);
$predisClient->ping();
//It's connected
}
catch (\Predis\Connection\ConnectionException $ce) {
self::$redisEnabled = false;
}
}
function testWithNullCache() {
$this->basicRun(null);
}
function testWithMemoryCache() {
$memoryCache = new \AddrCache\MemoryCache();
$this->basicRun($memoryCache);
}
/**
* @requires extension APC
*/
function testWithApcCache() {
$prefix = time().uniqid('CacheTest');
$apcCache = new \AddrCache\APCCache($prefix);
$this->basicRun($apcCache);
}
function testWithRedisCache() {
if (self::$redisEnabled != true) {
$this->markTestSkipped("Could not connect to Redis, skipping test.");
return;
}
$prefix = time().'_'.uniqid('CacheTest');
try {
$predisClient = new \Predis\Client(self::$redisParameters, []);
}
catch (\Predis\Connection\ConnectionException $ce) {
$this->markTestIncomplete("Could not connect to Redis server, cannot test redis cache.");
return;
}
$redisCache = new \AddrCache\RedisCache($predisClient, $prefix);
$this->basicRun($redisCache);
}
/**
* @group internet
*/
function basicRun(\AddrCache\Cache $cache = null) {
$names = [
'google.com',
'github.com',
'stackoverflow.com',
'localhost',
'192.168.0.1',
'::1',
];
$reactor = (new ReactorFactory)->select();
$resolver = (new ResolverFactory)->createResolver(
$reactor,
null, // $serverAddr = null,
null, //$serverPort = null,
null, //$requestTimeout = null,
$cache,
null //$hostsFilePath = null
);
$results = [];
foreach ($names as $name) {
$resolver->resolve($name, function($addr) use($name, $resolver, &$results) {
$results[$name] = $addr;
});
}
$reactor->run();
foreach ($results as $name => $addr) {
$validIP = filter_var($addr, FILTER_VALIDATE_IP);
$this->assertNotFalse(
$validIP,
"Server name $name did not resolve to a valid IP address"
);
}
$this->assertCount(
count($names),
$results,
"At least one of the name lookups did not resolve."
);
}
}

176
test/AddrTest/CacheTest.php Normal file
View File

@ -0,0 +1,176 @@
<?php
namespace AddrTest;
class CacheTest extends \PHPUnit_Framework_TestCase {
static private $redisEnabled = true;
static private $redisParameters = array(
'connection_timeout' => 2,
'read_write_timeout' => 2,
);
public static function setUpBeforeClass() {
try {
$predisClient = new \Predis\Client(self::$redisParameters, []);
$predisClient->ping();
//It's connected
}
catch (\Predis\Connection\ConnectionException $ce) {
self::$redisEnabled = false;
}
}
/**
* Create a mocked cache from the interface, and test that it works
* according to it's spec.
*/
function testCacheWorks() {
$mock = \Mockery::mock('AddrCache\Cache');
$cacheValues = [];
$cacheGetFunction = function($key) use (&$cacheValues) {
if (array_key_exists($key, $cacheValues)) {
return [true, $cacheValues[$key]];
}
return [false, null];
};
$cacheStoreFunction = function($key, $value, $ttl = null) use (&$cacheValues) {
$cacheValues[$key] = $value;
};
$cacheDeleteFunction = function($key) use (&$cacheValues) {
unset($cacheValues[$key]);
};
$mock->shouldReceive('get')->withAnyArgs()->andReturnUsing($cacheGetFunction);
$mock->shouldReceive('store')->withAnyArgs()->andReturnUsing($cacheStoreFunction);
$mock->shouldReceive('delete')->withAnyArgs()->andReturnUsing($cacheDeleteFunction);
$this->runCacheTest($mock);
}
/**
* Test that the APC cache works as expected. Skipped if APC is not available.
*
* @requires extension APC
*/
function testAPCCache() {
$result = @apc_cache_info();
if ($result === false) {
$this->markTestSkipped("APC does not appear to be functioning, skipping test testAPCCache.");
return;
}
$prefix = time().uniqid('CacheTest');
$apcCache = new \AddrCache\APCCache($prefix);
$this->runCacheTest($apcCache);
}
/**
* Test the redis cache works as expected.
*/
function testRedisCache() {
if (self::$redisEnabled == false) {
$this->markTestSkipped("Could not connect to Redis, skipping test.");
return;
}
$prefix = time().'_'.uniqid('CacheTest');
try {
$predisClient = new \Predis\Client(self::$redisParameters, []);
}
catch (\Predis\Connection\ConnectionException $ce) {
$this->markTestIncomplete("Could not connect to Redis server, cannot test redis cache.");
return;
}
$redisCache = new \AddrCache\RedisCache($predisClient, $prefix);
$this->runCacheTest($redisCache);
}
function testMemoryCache() {
$memoryCache = new \AddrCache\MemoryCache;
$this->runCacheTest($memoryCache);
}
/**
* Runs the actual test against an instance of a cache.
* @param \AddrCache\Cache $cache
*/
function runCacheTest(\AddrCache\Cache $cache) {
$key = 'TestKey';
$value = '12345';
$secondValue = '54321';
list($alreadyExisted, $retrievedValue) = $cache->get($key);
$this->assertFalse($alreadyExisted);
$this->assertNull($retrievedValue);
$cache->store($key, $value);
list($alreadyExisted, $retrievedValue) = $cache->get($key);
$this->assertTrue($alreadyExisted);
$this->assertEquals($value, $retrievedValue);
$cache->delete($key);
list($alreadyExisted, $retrievedValue) = $cache->get($key);
$this->assertFalse($alreadyExisted);
$this->assertNull($retrievedValue);
$cache->store($key, $secondValue);
list($alreadyExisted, $retrievedValue) = $cache->get($key);
$this->assertTrue($alreadyExisted);
$this->assertEquals($secondValue, $retrievedValue);
}
function testMemoryCacheGarbageCollection() {
$key = "TestKey";
$value = '12345';
$memoryCache = new \AddrCache\MemoryCache;
//A TTL of zero should be expired instantly
$memoryCache->store($key, $value, 0);
list($cacheHit, $cachedValue) = $memoryCache->get($key);
$this->assertFalse($cacheHit);
//A negative TTL oshould be expired instantly
$memoryCache->store($key, $value, -5);
list($cacheHit, $cachedValue) = $memoryCache->get($key);
$this->assertFalse($cacheHit);
//A positive TTL should be cached
$memoryCache->store($key, $value, 5);
list($cacheHit, $cachedValue) = $memoryCache->get($key);
$this->assertTrue($cacheHit);
$this->assertEquals($value, $cachedValue);
//check that garbage collection collects.
$memoryCache->store($key, $value, 0);
$memoryCache->collectGarbage();
//TODO - check that the memoryCache contains a single item
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace AddrTest;
use Addr\ResponseInterpreter;
class ResponseInterpreterTest extends \PHPUnit_Framework_TestCase{
function testCatchesExceptionAndReturnsNull() {
$decoder = \Mockery::mock('LibDNS\Decoder\Decoder');
$decoder->shouldReceive('decode')->withAnyArgs()->andThrow("Exception", "Testing bad packet");
$responseInterpreter = new ResponseInterpreter($decoder);
$result = $responseInterpreter->decode("SomePacket");
$this->assertNull($result);
}
function testInvalidMessage() {
$message = \Mockery::mock('LibDNS\Messages\Message');
$message->shouldReceive('getType')->once()->andReturn(\LibDNS\Messages\MessageTypes::QUERY);
$decoder = \Mockery::mock('LibDNS\Decoder\Decoder');
$decoder->shouldReceive('decode')->once()->andReturn($message);
$responseInterpreter = new ResponseInterpreter($decoder);
$result = $responseInterpreter->decode("SomePacket");
$this->assertNull($result);
}
function testInvalidResponseCode() {
$message = \Mockery::mock('LibDNS\Messages\Message');
$message->shouldReceive('getType')->once()->andReturn(\LibDNS\Messages\MessageTypes::RESPONSE);
$message->shouldReceive('getResponseCode')->once()->andReturn(42);
$decoder = \Mockery::mock('LibDNS\Decoder\Decoder');
$decoder->shouldReceive('decode')->once()->andReturn($message);
$responseInterpreter = new ResponseInterpreter($decoder);
$result = $responseInterpreter->decode("SomePacket");
$this->assertNull($result);
}
}

41
test/phpunit.xml Normal file
View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./testBootstrap.php">
<groups>
<exclude>
<group>SQL</group>
</exclude>
</groups>
<filter>
<whitelist>
<directory>../lib</directory>
</whitelist>
</filter>
<testsuites>
<testsuite name="Addr Test Suite">
<directory suffix=".php">./AddrTest/</directory>
</testsuite>
</testsuites>
<listeners>
<listener class="\Mockery\Adapter\Phpunit\TestListener"/>
</listeners>
<!-- <log type="coverage-text" target="php://stdout" showUncoveredFiles="false"/> -->
<logging>
<!-- <log type="junit" target="./var/logfile.xml" logIncompleteSkipped="false"/> -->
<log type="coverage-text" target="php://stdout" showUncoveredFiles="false"/>
<!-- Enabling coverage makes the tests take three times as long, as well
as take a bit of time to generate the HTML pages. -->
<!-- <log type="coverage-html" target="./coverage/" charset="UTF-8"
highlight="false" lowUpperBound="35" highLowerBound="70"/> -->
</logging>
</phpunit>

92
test/testBootstrap.php Normal file
View File

@ -0,0 +1,92 @@
<?php
use Auryn\Provider;
error_reporting(E_ALL);
$autoloader = require __DIR__.'/../vendor/autoload.php';
$autoloader->add('AddrTest', [realpath(__DIR__)."/"]);
function createProvider($implementations = array(), $shareClasses = array()) {
$provider = new Provider();
$standardImplementations = [
];
$standardShares = [
];
$redisParameters = array(
'connection_timeout' => 2,
'read_write_timeout' => 2,
);
$provider->define(
'Predis\Client',
array(
':parameters' => $redisParameters,
':options' => [],
)
);
$provider->share('Predis\Client');
setImplementations($provider, $standardImplementations, $implementations);
setShares($provider, $standardShares, $shareClasses);
$provider->share($provider); //YOLO
return $provider;
}
function setImplementations(Provider $provider, $standardImplementations, $implementations) {
foreach ($standardImplementations as $interface => $implementation) {
if (array_key_exists($interface, $implementations)) {
if (is_object($implementations[$interface]) == true) {
$provider->alias($interface, get_class($implementations[$interface]));
$provider->share($implementations[$interface]);
}
else {
$provider->alias($interface, $implementations[$interface]);
}
unset($implementations[$interface]);
}
else {
if (is_object($implementation)) {
$implementation = get_class($implementation);
}
$provider->alias($interface, $implementation);
}
}
foreach ($implementations as $class => $implementation) {
if (is_object($implementation) == true) {
$provider->alias($class, get_class($implementation));
$provider->share($implementation);
}
else {
$provider->alias($class, $implementation);
}
}
}
function setShares(Provider $provider, $standardShares, $shareClasses) {
foreach ($standardShares as $class => $share) {
if (array_key_exists($class, $shareClasses)) {
$provider->share($shareClasses[$class]);
unset($shareClasses[$class]);
}
else {
$provider->share($share);
}
}
foreach ($shareClasses as $class => $share) {
$provider->share($share);
}
}