Skip to content

Commit b8eefa1

Browse files
committed
Merge pull request #15 from hipchat/master
Support LDD feature retrieval
2 parents c747f4c + 4ccaf62 commit b8eefa1

23 files changed

+618
-121
lines changed

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
11
/vendor/
2-
/doc/
2+
/doc/
3+
*.iml
4+
composer.phar
5+
.vagrant
6+
integration-tests/vendor
7+
integration-tests/composer.lock

circle.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
machine:
22
php:
3-
version: 5.4.10
3+
version: 5.4.37
44

55
test:
66
override:
7-
- vendor/bin/phpunit tests
7+
- vendor/bin/phpunit tests

composer.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020
},
2121
"require-dev": {
2222
"phpunit/phpunit": "4.3.*",
23-
"phpdocumentor/phpdocumentor": "2.*"
23+
"phpdocumentor/phpdocumentor": "2.*",
24+
"predis/predis": "1.0.*"
25+
},
26+
"suggested": {
27+
"predis/predis": "1.0.*"
2428
},
2529
"autoload": {
2630
"psr-4": {

composer.lock

Lines changed: 57 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
namespace LaunchDarkly\Tests;
3+
4+
require_once 'vendor/autoload.php';
5+
6+
use LaunchDarkly\LDClient;
7+
use LaunchDarkly\LDUserBuilder;
8+
9+
class LDDFeatureRetrieverTest extends \PHPUnit_Framework_TestCase {
10+
11+
public function testGet() {
12+
$redis = new \Predis\Client(array(
13+
"scheme" => "tcp",
14+
"host" => 'localhost',
15+
"port" => 6379));
16+
$client = new LDClient("BOGUS_API_KEY", array('feature_requester_class' => '\\LaunchDarkly\\LDDFeatureRequester'));
17+
$builder = new LDUserBuilder(3);
18+
$user = $builder->build();
19+
20+
$redis->del("launchdarkly:features");
21+
$this->assertEquals("jim", $client->toggle('foo', $user, 'jim'));
22+
$redis->hset("launchdarkly:features", 'foo', $this->gen_feature("foo", "bar"));
23+
$this->assertEquals("bar", $client->toggle('foo', $user, 'jim'));
24+
}
25+
26+
public function testGetApc() {
27+
$redis = new \Predis\Client(array(
28+
"scheme" => "tcp",
29+
"host" => 'localhost',
30+
"port" => 6379));
31+
$client = new LDClient("BOGUS_API_KEY", array('feature_requester_class' => '\\LaunchDarkly\\ApcLDDFeatureRequester',
32+
'apc_expiration' => 1));
33+
$builder = new LDUserBuilder(3);
34+
$user = $builder->build();
35+
36+
$redis->del("launchdarkly:features");
37+
$this->assertEquals("jim", $client->toggle('foo', $user, 'jim'));
38+
$redis->hset("launchdarkly:features", 'foo', $this->gen_feature("foo", "bar"));
39+
$this->assertEquals("bar", $client->toggle('foo', $user, 'jim'));
40+
41+
# cached value so not updated
42+
$redis->hset("launchdarkly:features", 'foo', $this->gen_feature("foo", "baz"));
43+
$this->assertEquals("bar", $client->toggle('foo', $user, 'jim'));
44+
45+
apc_delete("launchdarkly:features.foo");
46+
$this->assertEquals("baz", $client->toggle('foo', $user, 'jim'));
47+
}
48+
49+
private function gen_feature($key, $val) {
50+
$data = <<<EOF
51+
{"name": "Feature $key", "key": "$key", "kind": "flag", "salt": "Zm9v", "on": true,
52+
"variations": [{"value": "$val", "weight": 100,
53+
"targets": [{"attribute": "key", "op": "in", "values": []}],
54+
"userTarget": {"attribute": "key", "op": "in", "values": []}},
55+
{"value": false, "weight": 0,
56+
"targets": [{"attribute": "key", "op": "in", "values": []}],
57+
"userTarget": {"attribute": "key", "op": "in", "values": []}}],
58+
"commitDate": "2015-09-08T21:24:16.712Z",
59+
"creationDate": "2015-09-08T21:06:16.527Z",
60+
"version": 4}
61+
EOF;
62+
return $data;
63+
}
64+
65+
}
66+

integration-tests/README.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
To run the tests, run:
2+
3+
vagrant up
4+
vagrant ssh
5+
cd project/integration-tests
6+
vendor/phpunit/phpunit/phpunit LDDFeatureRequesterTest.php
7+

integration-tests/Vagrantfile

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# -*- mode: ruby -*-
2+
# vi: set ft=ruby :
3+
4+
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
5+
VAGRANTFILE_API_VERSION = "2"
6+
7+
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
8+
# All Vagrant configuration is done here. The most common configuration
9+
# options are documented and commented below. For a complete reference,
10+
# please see the online documentation at vagrantup.com.
11+
12+
# Every Vagrant virtual environment requires a box to build off of.
13+
config.vm.box = "ubuntu/trusty64"
14+
15+
# The url from where the 'config.vm.box' box will be fetched if it
16+
# doesn't already exist on the user's system.
17+
config.vm.box_url = "https://vagrantcloud.com/ubuntu/boxes/trusty64"
18+
19+
config.vm.provision :shell, path: "bootstrap.sh"
20+
21+
# Create a forwarded port mapping which allows access to a specific port
22+
# within the machine from a port on the host machine. In the example below,
23+
# accessing "localhost:8080" will access port 80 on the guest machine.
24+
# config.vm.network :forwarded_port, guest: 80, host: 8080
25+
26+
# Create a private network, which allows host-only access to the machine
27+
# using a specific IP.
28+
# config.vm.network :private_network, ip: "192.168.33.10"
29+
30+
# Create a public network, which generally matched to bridged network.
31+
# Bridged networks make the machine appear as another physical device on
32+
# your network.
33+
# config.vm.network :public_network
34+
35+
# If true, then any SSH connections made will enable agent forwarding.
36+
# Default value: false
37+
# config.ssh.forward_agent = true
38+
39+
# Share an additional folder to the guest VM. The first argument is
40+
# the path on the host to the actual folder. The second argument is
41+
# the path on the guest to mount the folder. And the optional third
42+
# argument is a set of non-required options.
43+
config.vm.synced_folder "..", "/home/vagrant/project"
44+
45+
config.vm.provider :virtualbox do |vb|
46+
vb.auto_nat_dns_proxy = false
47+
vb.customize ["modifyvm", :id, "--natdnsproxy1", "off" ]
48+
vb.customize ["modifyvm", :id, "--natdnshostresolver1", "off" ]
49+
vb.customize ["modifyvm", :id, "--memory", "2048"]
50+
end
51+
end

integration-tests/bootstrap.sh

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/bin/bash
2+
3+
# init
4+
apt-get update 2> /dev/null
5+
6+
# redis
7+
apt-get install -y redis-server 2> /dev/null
8+
9+
# ntp
10+
apt-get install ntp -y 2> /dev/null
11+
service ntp restart
12+
13+
# install dependencies and services
14+
apt-get install unzip -y 2> /dev/null
15+
apt-get install -y vim curl 2> /dev/null
16+
apt-get install git -y 2> /dev/null
17+
18+
# PHP things
19+
echo "Install PHP things"
20+
apt-get install -y php-apc 2> /dev/null
21+
apt-get install -y phpunit 2> /dev/null
22+
23+
# phpbrew stuff for 5.4
24+
apt-get build-dep php5 2> /dev/null
25+
apt-get install -y php5 php5-dev php-pear autoconf automake curl build-essential libxslt1-dev re2c libxml2 libxml2-dev php5-cli bison libbz2-dev libreadline-dev 2> /dev/null
26+
apt-get install -y libfreetype6 libfreetype6-dev libpng12-0 libpng12-dev libjpeg-dev libjpeg8-dev libjpeg8 libgd-dev libgd3 libxpm4 libltdl7 libltdl-dev 2> /dev/null
27+
apt-get install -y libssl-dev openssl 2> /dev/null
28+
apt-get install -y gettext libgettextpo-dev libgettextpo0 2> /dev/null
29+
apt-get install -y php5-cli 2> /dev/null
30+
apt-get install -y libmcrypt-dev 2> /dev/null
31+
apt-get install -y libreadline-dev 2> /dev/null
32+
33+
# set vim tabs
34+
cat <<EOF > /home/vagrant/.vimrc
35+
set tabstop=4
36+
EOF
37+
chown vagrant.vagrant /home/vagrant/.vimrc
38+
39+
su - vagrant
40+
cd ~vagrant
41+
pwd
42+
curl -s -L -O https://github.com/phpbrew/phpbrew/raw/master/phpbrew
43+
chmod +x phpbrew
44+
sudo mv phpbrew /usr/bin/phpbrew
45+
phpbrew init
46+
phpbrew known --update
47+
phpbrew update
48+
phpbrew install 5.4.34 +default
49+
50+
echo "source $HOME/.phpbrew/bashrc" >> /home/vagrant/.bashrc
51+
source $HOME/.bashrc
52+
phpbrew switch php-5.4.34
53+
phpbrew ext install apc
54+
echo "apc.enable_cli = 1" >> ~/.phpbrew/php/php-5.4.34/etc/php.ini
55+
56+
57+
cd /home/vagrant/project/integration-tests
58+
curl -sS https://getcomposer.org/installer | php
59+
php composer.phar install

integration-tests/composer.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "launchdarkly/launchdarkly-php-integration-tests",
3+
"description": "Integration tests",
4+
"homepage": "https://github.com/launchdarkly/php-client",
5+
"license": "Apache-2.0",
6+
"authors": [
7+
{
8+
"name": "LaunchDarkly <team@launchdarkly.com>",
9+
"homepage": "http://launchdarkly.com/"
10+
}
11+
],
12+
"require": {
13+
"php": ">=5.3",
14+
"predis/predis": "1.0.*"
15+
},
16+
"require-dev": {
17+
"phpunit/phpunit": "4.3.*"
18+
},
19+
"autoload": {
20+
"psr-4": {
21+
"": "../src/"
22+
}
23+
},
24+
"autoload-dev": {
25+
"psr-4": {
26+
"": "."
27+
}
28+
}
29+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
namespace LaunchDarkly;
3+
4+
5+
/**
6+
* Feature requester from an LDD-populated redis, with APC caching
7+
*
8+
* @package LaunchDarkly
9+
*/
10+
class ApcLDDFeatureRequester extends LDDFeatureRequester {
11+
protected $_expiration = 30;
12+
13+
function __construct($baseUri, $apiKey, $options) {
14+
parent::__construct($baseUri, $apiKey, $options);
15+
16+
if (isset($options['apc_expiration'])) {
17+
$this->_expiration = (int)$options['apc_expiration'];
18+
}
19+
}
20+
21+
22+
protected function get_from_cache($key) {
23+
$key = self::make_cache_key($key);
24+
$enabled = apc_fetch($key);
25+
if ($enabled === false) {
26+
return null;
27+
}
28+
else {
29+
return $enabled;
30+
}
31+
}
32+
33+
protected function store_in_cache($key, $val) {
34+
apc_add($this->make_cache_key($key), $val, $this->_expiration);
35+
}
36+
37+
private function make_cache_key($name) {
38+
return $this->_features_key.'.'.$name;
39+
}
40+
}

0 commit comments

Comments
 (0)