diff --git a/CHANGES.txt b/CHANGES.txt index daaf68e9..6694a1e9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,8 @@ -7.1.1 (Feb 11, 2021) +7.1.1 (March XX, 2021) - Removed unused logic for HTTP and requests dependency. + - Removed all producer logic for Storages. + - Added SafeRedisWrapper for handling exception in Redis. + - Fixed typos in bucket and CONTRIBUTORS-GUIDE. 7.1.0 (Dec 3, 2021) - Added a new option to use when running Redis in cluster mode called `keyHashTags` which receives a list of hashtags from which the SDK will randomly pick one to use on the generated instance. diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 4c70c621..4f4db500 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -5,53 +5,61 @@ + tests/ - - tests/Suite/Redis/CacheInterfacesTest.php + + tests/Suite/Adapter + + + tests/Suite/Attributes/ tests/Suite/Common/ tests/Suite/Component/ + + + tests/Suite/DynamicConfigurations/ tests/Suite/Engine/ + + tests/Suite/InputValidation/ + tests/Suite/Matchers/ tests/Suite/Metrics/ + + tests/Suite/Redis/ + tests/Suite/Sdk/ - - tests/Suite/Attributes/ - - - tests/Suite/InputValidation/ - + tests/Suite/Adapter/ + tests/Suite/Attributes/ tests/Suite/Common/ tests/Suite/Component/ + tests/Suite/DynamicConfigurations/ tests/Suite/Engine/ + tests/Suite/InputValidation/ tests/Suite/Matchers/ tests/Suite/Metrics/ + tests/Suite/Redis/ tests/Suite/Sdk/ - tests/Suite/Adapter/ - tests/Suite/Attributes/ - tests/Suite/InputValidation/ - tests/Suite/DynamicConfigurations/ diff --git a/src/SplitIO/Component/Cache/Item.php b/src/SplitIO/Component/Cache/Item.php deleted file mode 100644 index af84f3de..00000000 --- a/src/SplitIO/Component/Cache/Item.php +++ /dev/null @@ -1,174 +0,0 @@ -assertValidKey($key); - $this->key = $key; - } - - /** - * Returns the key for the current cache item. - * - * The key is loaded by the Implementing Library, but should be available to - * the higher level callers when needed. - * - * @return string - * The key string for this cache item. - */ - public function getKey() - { - return (string) $this->key; - } - - /** - * Retrieves the value of the item from the cache associated with this object's key. - * - * The value returned must be identical to the value originally stored by set(). - * - * If isHit() returns false, this method MUST return null. Note that null - * is a legitimate cached value, so the isHit() method SHOULD be used to - * differentiate between "null value was found" and "no value was found." - * - * @return mixed - * The value corresponding to this cache item's key, or null if not found. - */ - public function get() - { - if (!$this->isHit()) { - return null; - } - - if ($this->value !== null) { - return $this->value; - } - } - - /** - * Confirms if the cache item lookup resulted in a cache hit. - * - * Note: This method MUST NOT have a race condition between calling isHit() - * and calling get(). - * - * @return bool - * True if the request resulted in a cache hit. False otherwise. - */ - public function isHit() - { - return $this->hit; - } - - /** - * Sets the value represented by this cache item. - * - * The $value argument may be any item that can be serialized by PHP, - * although the method of serialization is left up to the Implementing - * Library. - * - * @param mixed $value - * The serializable value to be stored. - * - * @return static - * The invoked object. - */ - public function set($value) - { - $this->value = $value; - $this->hit = true; - return $this; - } - - /** - * Sets the expiration time for this cache item. - * - * @param \DateTimeInterface $expiration - * The point in time after which the item MUST be considered expired. - * If null is passed explicitly, a default value MAY be used. If none is set, - * the value should be stored permanently or for as long as the - * implementation allows. - * - * @return static - * The called object. - */ - public function expiresAt($expiration) - { - // DateTimeInterface has been added for PHP>=5.5, so, also accept DateTime - if ($expiration instanceof DateTimeInterface || $expiration instanceof DateTime) { - // getting unix timestamp - $this->expire = (int) $expiration->format('U'); - } else { - $this->expire = 0; - } - - return $this; - } - - /** - * Sets the expiration time for this cache item. - * - * @param int|\DateInterval $time - * The period of time from the present after which the item MUST be considered - * expired. An integer parameter is understood to be the time in seconds until - * expiration. If null is passed explicitly, a default value MAY be used. - * If none is set, the value should be stored permanently or for as long as the - * implementation allows. - * - * @return static - * The called object. - */ - public function expiresAfter($time) - { - if ($time instanceof DateInterval) { - $expire = new DateTime(); - $expire->add($time); - // convert datetime to unix timestamp - $this->expire = (int) $expire->format('U'); - } elseif (is_int($time)) { - $this->expire = time() + $time; - } elseif (is_null($time)) { - $this->expire = 0; - } - - Di::getLogger()->info("//--> [CacheItem:{$this->key}] Set expiration time at: - {$this->expire} - ".date('Y-m-d H:i:s', $this->expire)); - - return $this; - } - - /** - * Returns the set expiration time as integer. - * @return int - */ - public function getExpiration() - { - return $this->expire; - } -} diff --git a/src/SplitIO/Component/Cache/Pool.php b/src/SplitIO/Component/Cache/Pool.php index 203a8a67..ae850078 100644 --- a/src/SplitIO/Component/Cache/Pool.php +++ b/src/SplitIO/Component/Cache/Pool.php @@ -1,8 +1,8 @@ adapter = new FilesystemAdapter($adapterOptions); - break;*/ - - case 'predis': - $this->adapter = new PRedisAdapter($adapterOptions); - break; + && is_array($options['adapter']['options'])) ? $options['adapter']['options'] : array(); - case 'redis': - default: - $this->adapter = new RedisAdapter($adapterOptions); - break; - } + $this->adapter = new SafeRedisWrapper(new PredisAdapter($adapterOptions)); } /** @@ -51,14 +34,13 @@ public function __construct(array $options = array()) * If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException * MUST be thrown. * - * @return \SplitIO\Component\Cache\Item - * The corresponding Cache Item. + * @return string */ - public function getItem($key) + public function get($key) { $this->assertValidKey($key); Di::getLogger()->debug("Fetching item ** $key ** from cache"); - return $this->adapter->getItem($key); + return $this->adapter->get($key); } /** @@ -77,161 +59,9 @@ public function getItem($key) * key is not found. However, if no keys are specified then an empty * traversable MUST be returned instead. */ - public function getItems(array $keys = array()) - { - return $this->adapter->getItems($keys); - } - - /** - * Confirms if the cache contains specified cache item. - * - * Note: This method MAY avoid retrieving the cached value for performance reasons. - * This could result in a race condition with CacheItemInterface::get(). To avoid - * such situation use CacheItemInterface::isHit() instead. - * - * @param string $key - * The key for which to check existence. - * - * @throws \InvalidArgumentException - * If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException - * MUST be thrown. - * - * @return bool - * True if item exists in the cache, false otherwise. - */ - public function hasItem($key) - { - $this->assertValidKey($key); - - $item = $this->getItem($key); - return $item->isHit(); - } - - /** - * Deletes all items in the pool. - * - * @return bool - * True if the pool was successfully cleared. False if there was an error. - */ - public function clear() - { - return $this->adapter->clear(); - } - - /** - * Removes the item from the pool. - * - * @param string $key - * The key for which to delete - * - * @throws \InvalidArgumentException - * If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException - * MUST be thrown. - * - * @return bool - * True if the item was successfully removed. False if there was an error. - */ - public function deleteItem($key) - { - $this->assertValidKey($key); - - return $this->adapter->deleteItem($key); - } - - /** - * Removes multiple items from the pool. - * - * @param array $keys - * An array of keys that should be removed from the pool. - - * @throws \InvalidArgumentException - * If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException - * MUST be thrown. - * - * @return bool - * True if the items were successfully removed. False if there was an error. - */ - public function deleteItems(array $keys) - { - foreach ($keys as $key) { - $this->assertValidKey($key); - } - - return $this->adapter->deleteItems($keys); - } - - /** - * Persists a cache item immediately. - * - * @param \SplitIO\Component\Cache\Item $item - * The cache item to save. - * - * @return bool - * True if the item was successfully persisted. False if there was an error. - */ - public function save(Item $item) - { - $key = $item->getKey(); - $value = $item->get(); - - //PSR-6 CacheItemInterface doesn't define a method to get the item expiration value. - $expiration = (method_exists($item, 'getExpiration')) ? $item->getExpiration() : 0; - - if ($this->adapter->save($key, $value, $expiration)) { - Di::getLogger()->debug("Saving cache item: $key - $value - $expiration"); - return true; - } - - return false; - } - - /** - * Sets a cache item to be persisted later. - * - * @param \SplitIO\Component\Cache\Item $item - * The cache item to save. - * - * @return bool - * False if the item could not be queued or if a commit was attempted and failed. True otherwise. - */ - public function saveDeferred(Item $item) - { - $this->deferred[] = $item; - return true; - } - - /** - * Persists any deferred cache items. - * - * @return bool - * True if all not-yet-saved items were successfully saved or there were none. False otherwise. - */ - public function commit() - { - $success = true; - - foreach ($this->deferred as $item) { - if (! $this->save($item)) { - $success = false; - } - } - - if ($success) { - $this->deferred = array(); - } - - return $success; - } - - - public function saveItemOnList($key, $value) - { - return $this->adapter->addItemList($key, $value); - } - - public function removeItemOnList($key, $value) + public function fetchMany(array $keys = array()) { - return $this->adapter->removeItemList($key, $value); + return $this->adapter->fetchMany($keys); } public function isItemOnList($key, $value) @@ -239,31 +69,11 @@ public function isItemOnList($key, $value) return $this->adapter->isOnList($key, $value); } - public function getItemsOnList($key) - { - return $this->adapter->getListItems($key); - } - - public function getItemsRandomlyOnList($key, $count) - { - return $this->adapter->getListItemsRandomly($key, $count); - } - public function getKeys($pattern = '*') { return $this->adapter->getKeys($pattern); } - public function incrementKey($key) - { - return $this->adapter->incrementKey($key); - } - - public function getSet($key, $value) - { - return $this->adapter->getSet($key, $value); - } - public function rightPushInList($queue, $item) { return $this->adapter->rightPushQueue($queue, $item); diff --git a/src/SplitIO/Component/Cache/SegmentCache.php b/src/SplitIO/Component/Cache/SegmentCache.php index ee830d84..8ea79d78 100644 --- a/src/SplitIO/Component/Cache/SegmentCache.php +++ b/src/SplitIO/Component/Cache/SegmentCache.php @@ -5,17 +5,10 @@ class SegmentCache implements SegmentCacheInterface { - const KEY_REGISTER_SEGMENTS = 'SPLITIO.segments.registered'; - const KEY_SEGMENT_DATA = 'SPLITIO.segment.{segmentName}'; const KEY_TILL_CACHED_ITEM = 'SPLITIO.segment.{segment_name}.till'; - private static function getCacheKeyForRegisterSegments() - { - return self::KEY_REGISTER_SEGMENTS; - } - private static function getCacheKeyForSegmentData($segmentName) { return str_replace('{segmentName}', $segmentName, self::KEY_SEGMENT_DATA); @@ -26,60 +19,6 @@ private static function getCacheKeyForSinceParameter($segmentName) return str_replace('{segment_name}', $segmentName, self::KEY_TILL_CACHED_ITEM); } - /** - * @param $segmentName - * @return boolean - */ - public static function registerSegment($segmentName) - { - $cache = Di::getCache(); - - return $cache->saveItemOnList(self::getCacheKeyForRegisterSegments(), $segmentName); - } - - public static function getRegisteredSegments() - { - return Di::getCache()->getItemsOnList(self::getCacheKeyForRegisterSegments()); - } - - /** - * @param $segmentName - * @param $segmentKeys - * @return mixed - */ - public function addToSegment($segmentName, array $segmentKeys) - { - $cache = Di::getCache(); - $return = array(); - - $segmentDataKey = self::getCacheKeyForSegmentData($segmentName); - - foreach ($segmentKeys as $key) { - $return[$key] = $cache->saveItemOnList($segmentDataKey, $key); - } - - return $return; - } - - /** - * @param $segmentName - * @param array $segmentKeys - * @return mixed - */ - public function removeFromSegment($segmentName, array $segmentKeys) - { - $cache = Di::getCache(); - $return = array(); - - $segmentDataKey = self::getCacheKeyForSegmentData($segmentName); - - foreach ($segmentKeys as $key) { - $return[$key] = $cache->removeItemOnList($segmentDataKey, $key); - } - - return $return; - } - /** * @param $segmentName * @param $key @@ -91,28 +30,14 @@ public function isInSegment($segmentName, $key) return Di::getCache()->isItemOnList($segmentDataKey, $key); } - /** - * @param $segmentName - * @param $changeNumber - * @return mixed - */ - public function setChangeNumber($segmentName, $changeNumber) - { - $sinceKey = self::getCacheKeyForSinceParameter($segmentName); - $since_cached_item = Di::getCache()->getItem($sinceKey); - Di::getLogger()->info(">>> SINCE CACHE KEY: $sinceKey"); - $since_cached_item->set($changeNumber); - - return Di::getCache()->save($since_cached_item); - } - /** * @param $segmentName * @return mixed */ public function getChangeNumber($segmentName) { - $since = Di::getCache()->getItem(self::getCacheKeyForSinceParameter($segmentName))->get(); + $since = Di::getCache()->get(self::getCacheKeyForSinceParameter($segmentName)); + // empty check for nullable value return (empty($since)) ? -1 : $since; } } diff --git a/src/SplitIO/Component/Cache/SegmentCacheInterface.php b/src/SplitIO/Component/Cache/SegmentCacheInterface.php index 58668e80..14e53235 100644 --- a/src/SplitIO/Component/Cache/SegmentCacheInterface.php +++ b/src/SplitIO/Component/Cache/SegmentCacheInterface.php @@ -3,20 +3,6 @@ interface SegmentCacheInterface { - /** - * @param $segmentName - * @param $segmentKeys - * @return mixed - */ - public function addToSegment($segmentName, array $segmentKeys); - - /** - * @param $segmentName - * @param array $segmentKeys - * @return mixed - */ - public function removeFromSegment($segmentName, array $segmentKeys); - /** * @param $segmentName * @param $key @@ -24,13 +10,6 @@ public function removeFromSegment($segmentName, array $segmentKeys); */ public function isInSegment($segmentName, $key); - /** - * @param $segmentName - * @param $changeNumber - * @return mixed - */ - public function setChangeNumber($segmentName, $changeNumber); - /** * @param $segmentName * @return mixed diff --git a/src/SplitIO/Component/Cache/SplitCache.php b/src/SplitIO/Component/Cache/SplitCache.php index 6ef11782..dd7bac55 100644 --- a/src/SplitIO/Component/Cache/SplitCache.php +++ b/src/SplitIO/Component/Cache/SplitCache.php @@ -32,46 +32,13 @@ private static function getSplitNameFromCacheKey($key) return str_replace($cacheKeyPrefix, '', $key); } - /** - * @param string $splitName - * @param string $split JSON representation - * @return boolean - */ - public function addSplit($splitName, $split) - { - $cache = Di::getCache(); - $cacheItem = $cache->getItem(self::getCacheKeyForSplit($splitName)); - $cacheItem->set($split); - return $cache->save($cacheItem); - } - - /** - * @param string $splitName - * @return boolean - */ - public function removeSplit($splitName) - { - return Di::getCache()->deleteItem(self::getCacheKeyForSplit($splitName)); - } - - /** - * @param long $changeNumber - * @return boolean - */ - public function setChangeNumber($changeNumber) - { - $since_cached_item = Di::getCache()->getItem(self::getCacheKeyForSinceParameter()); - $since_cached_item->set($changeNumber); - - return Di::getCache()->save($since_cached_item); - } - /** * @return long */ public function getChangeNumber() { - $since = Di::getCache()->getItem(self::getCacheKeyForSinceParameter())->get(); + $since = Di::getCache()->get(self::getCacheKeyForSinceParameter()); + // empty check for nullable value return (empty($since)) ? -1 : $since; } @@ -82,8 +49,8 @@ public function getChangeNumber() public function getSplit($splitName) { $cache = Di::getCache(); - $cacheItem = $cache->getItem(self::getCacheKeyForSplit($splitName)); - return $cacheItem->get(); + $cacheItem = $cache->get(self::getCacheKeyForSplit($splitName)); + return $cacheItem; } /** @@ -93,10 +60,10 @@ public function getSplit($splitName) public function getSplits($splitNames) { $cache = Di::getCache(); - $cacheItems = $cache->getItems(array_map('self::getCacheKeyForSplit', $splitNames)); + $cacheItems = $cache->fetchMany(array_map('self::getCacheKeyForSplit', $splitNames)); $toReturn = array(); foreach ($cacheItems as $key => $value) { - $toReturn[self::getSplitNameFromCacheKey($key)] = $value->get(); + $toReturn[self::getSplitNameFromCacheKey($key)] = $value; } return $toReturn; } @@ -133,7 +100,8 @@ public function trafficTypeExists($trafficType) { $cache = Di::getCache(); - $count = $cache->getItem(self::getCacheKeyForTrafficType($trafficType))->get(); + $count = $cache->get(self::getCacheKeyForTrafficType($trafficType)); + // empty check for nullable value return (empty($count) || $count < 1) ? false : true; } } diff --git a/src/SplitIO/Component/Cache/SplitCacheInterface.php b/src/SplitIO/Component/Cache/SplitCacheInterface.php index b741b958..1321466a 100644 --- a/src/SplitIO/Component/Cache/SplitCacheInterface.php +++ b/src/SplitIO/Component/Cache/SplitCacheInterface.php @@ -3,25 +3,6 @@ interface SplitCacheInterface { - /** - * @param string $splitName - * @param string $split JSON representation - * @return boolean - */ - public function addSplit($splitName, $split); - - /** - * @param string $splitName - * @return boolean - */ - public function removeSplit($splitName); - - /** - * @param long $changeNumber - * @return boolean - */ - public function setChangeNumber($changeNumber); - /** * @return long */ diff --git a/src/SplitIO/Component/Cache/Storage/Adapter/CacheStorageAdapterInterface.php b/src/SplitIO/Component/Cache/Storage/Adapter/CacheStorageAdapterInterface.php index 1d9d8f29..c193e191 100644 --- a/src/SplitIO/Component/Cache/Storage/Adapter/CacheStorageAdapterInterface.php +++ b/src/SplitIO/Component/Cache/Storage/Adapter/CacheStorageAdapterInterface.php @@ -4,7 +4,7 @@ interface CacheStorageAdapterInterface { - public function __construct(array $options); + // public function __construct(array $options); /** * @param null|string $pattern @@ -14,62 +14,11 @@ public function getKeys($pattern = '*'); /** * @param string $key - * @return \SplitIO\Component\Cache\Item + * @return string */ - public function getItem($key); + public function get($key); - public function getItems(array $keys); - - /** - * @param string $key - * @param mixed $value - * @param int|null $expiration - * @return bool - */ - public function addItem($key, $value, $expiration = null); - - - /** - * @return bool - */ - public function clear(); - - /** - * @param $key - * @return bool - */ - public function deleteItem($key); - - /** - * @param array $keys - * @return bool - */ - public function deleteItems(array $keys); - - /** - * @param $key - * @param $value - * @param int|null $expiration - * @return bool - */ - public function save($key, $value, $expiration = null); - - /** - * Adds a values to the set value stored at key. - * If this value is already in the set, FALSE is returned. - * - * @param $key - * @param $value - * @return boolean - */ - public function addItemList($key, $value); - - /** - * @param $key - * @param $value - * @return mixed - */ - public function removeItemList($key, $value); + public function fetchMany(array $keys); /** * @param $key @@ -78,25 +27,6 @@ public function removeItemList($key, $value); */ public function isOnList($key, $value); - /** - * @param $key - * @return mixed - */ - public function getListItems($key); - - /** - * @param $key - * @return int - */ - public function incrementKey($key); - - /** - * @param $key - * @param $value - * @return mixed - */ - public function getSet($key, $value); - /** * @param $queueName * @param $item diff --git a/src/SplitIO/Component/Cache/Storage/Adapter/Filesystem.php b/src/SplitIO/Component/Cache/Storage/Adapter/Filesystem.php deleted file mode 100644 index 1997c6c8..00000000 --- a/src/SplitIO/Component/Cache/Storage/Adapter/Filesystem.php +++ /dev/null @@ -1,162 +0,0 @@ - self::DEFAULT_PATH, - 'ttl' => self::DEFAULT_VALUE_TTL - ); - - /** - * @param array $options - */ - public function __construct(array $options) - { - $this->options = array_merge($this->options, $options); - - $this->options['path'] = (!isset($options['path'])) ? sys_get_temp_dir() : $options['path']; - - if (!is_writable($this->options['path'])) { - throw new AdapterException($this->options['path']." is not writable."); - } - - $this->path = rtrim($this->options['path'], '/'); - } - - /** - * @param string $key - * @return \Psr\Cache\CacheItemInterface - */ - public function getItem($key) - { - $item = new Item($key); - - $file = $this->getFilePath($key); - Di::getInstance()->getLogger()->debug("Cache file: $file"); - - if (file_exists($file)) { - $data = unserialize(file_get_contents($file)); - $expiration = (int) $data['expiration']; - - if ($expiration !== 0 && $expiration < time()) { - // expired - $time = time(); - Di::getInstance()->getLogger()->debug("//--> Fetched item $key expired at $expiration, NOw($time)"); - return $item; - } - - $item->set(unserialize($data['value'])); - } - - return $item; - } - - /** - * @param string $key - * @param mixed $value - * @param int|null $expiration - * @return bool - */ - public function addItem($key, $value, $expiration = null) - { - return $this->save($key, $value, $expiration); - } - - /** - * @return bool - */ - public function clear() - { - $files = glob($this->path.'/'.self::DEFAULT_FILENAME_PREFIX.'.*.'.self::DEFAULT_FILENAME_EXTENSION); - $success = true; - foreach ($files as $file) { - $success &= @unlink($file); - } - return $success; - } - - /** - * @param $key - * @return bool - */ - public function deleteItem($key) - { - $file = $this->getFilePath($key); - - if (file_exists($file)) { - return @unlink($file); - } - - return false; - } - - /** - * @param array $keys - * @return bool - */ - public function deleteItems(array $keys) - { - foreach ($keys as $key) { - if (! $this->deleteItem($key)) { - return false; - } - } - - return true; - } - - /** - * @param $key - * @param $value - * @param int|null $expiration - * @return bool - */ - public function save($key, $value, $expiration = null) - { - if ($expiration === 0 || $expiration === null) { - $expirationToSet = time() + $this->options['ttl']; - } else { - $expirationToSet = $expiration; - } - - $data = array('expiration' => $expirationToSet, 'value' => serialize($value)); - $success = file_put_contents($this->getFilePath($key), serialize($data), \LOCK_EX); - return $success !== false; - } - - /** - * @param $key - * @return string - */ - private function getFilePath($key) - { - return $this->options['path'].'/'.self::DEFAULT_FILENAME_PREFIX.'.'. - urlencode($key).'.'.self::DEFAULT_FILENAME_EXTENSION; - } -} diff --git a/src/SplitIO/Component/Cache/Storage/Adapter/PRedis.php b/src/SplitIO/Component/Cache/Storage/Adapter/PRedis.php index b3f9d60c..baa48086 100644 --- a/src/SplitIO/Component/Cache/Storage/Adapter/PRedis.php +++ b/src/SplitIO/Component/Cache/Storage/Adapter/PRedis.php @@ -205,19 +205,11 @@ private function getRedisConfiguration($options) /** * @param string $key - * @return \SplitIO\Component\Cache\Item + * @return string */ - public function getItem($key) + public function get($key) { - $item = new Item($key); - - $redisItem = $this->client->get($key); - - if ($redisItem !== null) { - $item->set($redisItem); - } - - return $item; + return $this->client->get($key); } @@ -231,108 +223,21 @@ public function getItem($key) * If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException * MUST be thrown. * - * @return array|\Traversable - * A traversable collection of Cache Items keyed by the cache keys of - * each item. A Cache item will be returned for each key, even if that - * key is not found. However, if no keys are specified then an empty - * traversable MUST be returned instead. + * @return array */ - public function getItems(array $keys = array()) + public function fetchMany(array $keys = array()) { - $values = $this->client->mget($keys); $toReturn = array(); + if (count($keys) == 0) { + return $toReturn; + } + $values = $this->client->mget($keys); foreach ($keys as $index => $key) { - $toReturn[$key] = new Item($key); - if (!is_null($values[$index])) { - $toReturn[$key]->set($values[$index]); - } + $toReturn[$key] = $values[$index]; } return $toReturn; } - /** - * @param string $key - * @param mixed $value - * @param int|null $expiration - * @return bool - */ - public function addItem($key, $value, $expiration = null) - { - return $this->save($key, $value, $expiration); - } - - /** - * @return bool - */ - public function clear() - { - return $this->client->flushAll(); - } - - /** - * @param $key - * @return bool - */ - public function deleteItem($key) - { - $return = $this->client->del($key); - - if ($return > 0) { - return true; - } - - return false; - } - - /** - * @param array $keys - * @return bool - */ - public function deleteItems(array $keys) - { - $return = $this->client->del($keys); - - if ($return > 0) { - return true; - } - - return false; - } - - /** - * @param $key - * @param $value - * @param int|null $expiration - * @return bool - */ - public function save($key, $value, $expiration = null) - { - return $this->client->set($key, $value); - } - - /** - * Adds a values to the set value stored at key. - * If this value is already in the set, FALSE is returned. - * - * @param $key - * @param $value - * @return boolean - */ - public function addItemList($key, $value) - { - return $this->client->sAdd($key, $value); - } - - /** - * @param $key - * @param $value - * @return mixed - */ - public function removeItemList($key, $value) - { - return $this->client->sRem($key, $value); - } - /** * @param $key * @param $value @@ -343,20 +248,6 @@ public function isOnList($key, $value) return $this->client->sIsMember($key, $value); } - /** - * @param $key - * @return mixed - */ - public function getListItems($key) - { - return $this->client->sMembers($key); - } - - public function getListItemsRandomly($key, $count) - { - return $this->client->srandmember($key, $count); - } - public function getKeys($pattern = '*') { $prefix = null; @@ -386,16 +277,6 @@ public function getKeys($pattern = '*') return $keys; } - public function incrementKey($key) - { - return $this->client->incr($key); - } - - public function getSet($key, $value) - { - return $this->client->getSet($key, $value); - } - private static function normalizePrefix($prefix) { if ($prefix && strlen($prefix)) { diff --git a/src/SplitIO/Component/Cache/Storage/Adapter/Redis.php b/src/SplitIO/Component/Cache/Storage/Adapter/Redis.php deleted file mode 100644 index f1f81dcb..00000000 --- a/src/SplitIO/Component/Cache/Storage/Adapter/Redis.php +++ /dev/null @@ -1,230 +0,0 @@ - self::DEFAULT_HOST, - 'port' => self::DEFAULT_PORT, - 'timeout' => self::DEFAULT_TIMEOUT, - 'ttl' => self::DEFAULT_VALUE_TTL, - 'password' => false - ); - - /** - * @param array $options - * @throws AdapterException - */ - public function __construct(array $options) - { - if (!extension_loaded('redis')) { - throw new AdapterException("Redis extension is not loaded"); - } - - $host = (isset($options['host'])) ? $options['host'] : self::DEFAULT_HOST; - $port = (isset($options['port'])) ? $options['port'] : self::DEFAULT_PORT; - $timeout = (isset($options['timeout'])) ? (float) $options['timeout'] : self::DEFAULT_TIMEOUT; - $password = (isset($options['password'])) ? $options['password'] : false; - - $this->client = new \Redis(); - - if (! $this->client->connect($host, $port, $timeout)) { - throw new AdapterException("Redis servers cannot be connected"); - } - - if ($password !== false) { - $this->client->auth($password); - } - - $this->options = array_merge($this->options, $options); - } - - /** - * @param string $key - * @return \SplitIO\Component\Cache\Item - */ - public function getItem($key) - { - $item = new Item($key); - - $redisItem = $this->client->get($key); - - if ($redisItem !== false) { - $item->set($redisItem); - } - - return $item; - } - - /** - * Returns a traversable set of cache items. - * - * @param array $keys - * An indexed array of keys of items to retrieve. - * - * @throws \InvalidArgumentException - * If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException - * MUST be thrown. - * - * @return array|\Traversable - * A traversable collection of Cache Items keyed by the cache keys of - * each item. A Cache item will be returned for each key, even if that - * key is not found. However, if no keys are specified then an empty - * traversable MUST be returned instead. - */ - public function getItems(array $keys = array()) - { - return $this->client->mget($keys); - } - - /** - * @param string $key - * @param mixed $value - * @param int|null $expiration - * @return bool - */ - public function addItem($key, $value, $expiration = null) - { - return $this->save($key, $value, $expiration); - } - - /** - * @return bool - */ - public function clear() - { - return $this->client->flushAll(); - } - - /** - * @param $key - * @return bool - */ - public function deleteItem($key) - { - $return = $this->client->del($key); - - if ($return > 0) { - return true; - } - - return false; - } - - /** - * @param array $keys - * @return bool - */ - public function deleteItems(array $keys) - { - $return = $this->client->del($keys); - - if ($return > 0) { - return true; - } - - return false; - } - - /** - * @param $key - * @param $value - * @param int|null $expiration - * @return bool - */ - public function save($key, $value, $expiration = null) - { - /* - if ($expiration === 0 || $expiration === null) { - $expirationToSet = $this->options['ttl']; - } else { - $expirationToSet = $expiration - time(); - } - - return $this->client->setex($key, $expirationToSet, serialize($value)); - */ - - return $this->client->set($key, $value); - } - - /** - * Adds a values to the set value stored at key. - * If this value is already in the set, FALSE is returned. - * - * @param $key - * @param $value - * @return boolean - */ - public function addItemList($key, $value) - { - return $this->client->sAdd($key, $value); - } - - /** - * @param $key - * @param $value - * @return mixed - */ - public function removeItemList($key, $value) - { - return $this->client->sRem($key, $value); - } - - /** - * @param $key - * @param $value - * @return mixed - */ - public function isOnList($key, $value) - { - return $this->client->sIsMember($key, $value); - } - - /** - * @param $key - * @return mixed - */ - public function getListItems($key) - { - return $this->client->sMembers($key); - } - - public function getKeys($pattern = '*') - { - return $this->client->keys($pattern); - } - - public function incrementKey($key) - { - return $this->client->incr($key); - } - - public function getSet($key, $value) - { - return $this->client->getSet($key, $value); - } -} diff --git a/src/SplitIO/Component/Cache/Storage/Adapter/SafeRedisWrapper.php b/src/SplitIO/Component/Cache/Storage/Adapter/SafeRedisWrapper.php new file mode 100644 index 00000000..9d7a9f4d --- /dev/null +++ b/src/SplitIO/Component/Cache/Storage/Adapter/SafeRedisWrapper.php @@ -0,0 +1,129 @@ +cacheAdapter = $cacheAdapter; + } + + /** + * @param string $key + * @return string + */ + public function get($key) + { + try { + return $this->cacheAdapter->get($key); + } catch (\Exception $e) { + Di::getLogger()->critical("An error occurred getting " . $key . " from redis."); + Di::getLogger()->critical($e->getMessage()); + Di::getLogger()->critical($e->getTraceAsString()); + return null; + } + } + + + /** + * Returns a traversable set of cache items. + * + * @param array $keys + * An indexed array of keys of items to retrieve. + * + * @return array + */ + public function fetchMany(array $keys = array()) + { + try { + return $this->cacheAdapter->fetchMany($keys); + } catch (\Exception $e) { + Di::getLogger()->critical("An error occurred getting " . json_encode($keys) . " from redis."); + Di::getLogger()->critical($e->getMessage()); + Di::getLogger()->critical($e->getTraceAsString()); + return array(); + } + } + + /** + * @param $key + * @param $value + * @return mixed + */ + public function isOnList($key, $value) + { + try { + return $this->cacheAdapter->isOnList($key, $value); + } catch (\Exception $e) { + Di::getLogger()->critical("An error occurred for " . $key); + Di::getLogger()->critical($e->getMessage()); + Di::getLogger()->critical($e->getTraceAsString()); + return false; + } + } + + /** + * @param $pattern + * @return mixed|null + */ + public function getKeys($pattern = '*') + { + try { + return $this->cacheAdapter->getKeys($pattern); + } catch (\Exception $e) { + Di::getLogger()->critical("An error occurred getting " . $pattern); + Di::getLogger()->critical($e->getMessage()); + Di::getLogger()->critical($e->getTraceAsString()); + return array(); + } + } + + /** + * @param $queueName + * @param $item + * @return number + */ + public function rightPushQueue($queueName, $item) + { + try { + return $this->cacheAdapter->rightPushQueue($queueName, $item); + } catch (\Exception $e) { + Di::getLogger()->critical("An error occurred performing RPUSH into " . $queueName); + Di::getLogger()->critical($e->getMessage()); + Di::getLogger()->critical($e->getTraceAsString()); + return 0; + } + } + + /** + * @param $key + * @param $ttl + * @return mixed + */ + public function expireKey($key, $ttl) + { + try { + return $this->cacheAdapter->expireKey($key, $ttl); + } catch (\Exception $e) { + Di::getLogger()->critical("An error occurred setting expiration for " . $key); + Di::getLogger()->critical($e->getMessage()); + Di::getLogger()->critical($e->getTraceAsString()); + return false; + } + } +} diff --git a/src/SplitIO/Component/Initialization/CacheTrait.php b/src/SplitIO/Component/Initialization/CacheTrait.php index f10f8eae..e83802b2 100644 --- a/src/SplitIO/Component/Initialization/CacheTrait.php +++ b/src/SplitIO/Component/Initialization/CacheTrait.php @@ -8,45 +8,21 @@ class CacheTrait { public static function addCache($adapter, array $options) { - switch ($adapter) { - case 'filesystem': - $adapter_config = array( - 'name' => 'filesystem', - 'options' => array( - 'path'=> isset($options['filesystem-path']) ? $options['filesystem-path'] : null - ) - ); - break; - case 'predis': - $adapter_config = array( - 'name' => 'predis', - 'options' => array( - 'options' => isset($options['predis-options']) - ? $options['predis-options'] : null, - 'parameters' => isset($options['predis-parameters']) - ? $options['predis-parameters'] : null, - 'sentinels' => isset($options['predis-sentinels']) - ? $options['predis-sentinels'] : null, - 'clusterNodes' => isset($options['predis-clusterNodes']) - ? $options['predis-clusterNodes'] : null, - 'distributedStrategy' => isset($options['predis-distributedStrategy']) - ? $options['predis-distributedStrategy'] : null, - ) - ); - break; - case 'redis': - default: - $adapter_config = array( - 'name' => 'redis', - 'options' => array( - 'host' => isset($options['redis-host']) ? $options['redis-host'] : null, - 'port' => isset($options['redis-port']) ? $options['redis-port'] : null, - 'password' => isset($options['redis-pass']) ? $options['redis-pass'] : null, - 'timeout' => isset($options['redis-timeout']) ? $options['redis-timeout'] : null, - ) - ); - break; - } + $adapter_config = array( + 'name' => 'predis', + 'options' => array( + 'options' => isset($options['predis-options']) + ? $options['predis-options'] : null, + 'parameters' => isset($options['predis-parameters']) + ? $options['predis-parameters'] : null, + 'sentinels' => isset($options['predis-sentinels']) + ? $options['predis-sentinels'] : null, + 'clusterNodes' => isset($options['predis-clusterNodes']) + ? $options['predis-clusterNodes'] : null, + 'distributedStrategy' => isset($options['predis-distributedStrategy']) + ? $options['predis-distributedStrategy'] : null, + ) + ); ServiceProvider::registerCache(new Pool(array('adapter' => $adapter_config))); } diff --git a/src/SplitIO/Sdk/Factory/SplitFactory.php b/src/SplitIO/Sdk/Factory/SplitFactory.php index 75476c8d..87852808 100644 --- a/src/SplitIO/Sdk/Factory/SplitFactory.php +++ b/src/SplitIO/Sdk/Factory/SplitFactory.php @@ -46,14 +46,17 @@ public function __construct($apiKey, array $options = array()) private function doBUR() { - $ready = (isset($this->options['ready']) && $this->options['ready'] > 0) ? $this->options['ready'] : null; + /* + Deprecated + $ready = (isset($this->options['ready']) && $this->options['ready'] > 0) ? $this->options['ready'] : null; - //Block Until Ready - if ($ready) { - if (!$this->blockUntilReady($ready)) { - throw new TimeOutException("Cache data is not ready yet"); + //Block Until Ready + if ($ready) { + if (!$this->blockUntilReady($ready)) { + throw new TimeOutException("Cache data is not ready yet"); + } } - } + */ } /** diff --git a/src/SplitIO/Version.php b/src/SplitIO/Version.php index 82c55f86..ac68bb10 100644 --- a/src/SplitIO/Version.php +++ b/src/SplitIO/Version.php @@ -3,5 +3,5 @@ class Version { - const CURRENT = '7.1.1-rc2'; + const CURRENT = '7.1.1-rc5'; } diff --git a/tests/Suite/Adapter/RedisAdapterTest.php b/tests/Suite/Adapter/RedisAdapterTest.php index 7708f6ea..4b14d2be 100644 --- a/tests/Suite/Adapter/RedisAdapterTest.php +++ b/tests/Suite/Adapter/RedisAdapterTest.php @@ -43,11 +43,16 @@ public function testRedisWithOnlyParameters() 'database' => 0 ) )); - $predis->addItem('this_is_a_test_key', 'this-is-a-test-value'); - $value = $predis->getItem('this_is_a_test_key'); - $this->assertEquals('this-is-a-test-value', $value->get()); - $result = $predis->deleteItem('this_is_a_test_key'); - $this->assertTrue($result); + $predisClient = new \Predis\Client([ + 'host' => REDIS_HOST, + 'port' => REDIS_PORT, + ]); + $predisClient->set('this_is_a_test_key', 'this-is-a-test-value'); + + $value = $predis->get('this_is_a_test_key'); + $this->assertEquals('this-is-a-test-value', $value); + + $predisClient->del('this_is_a_test_key'); } public function testRedisWithParametersAndPrefix() @@ -64,11 +69,16 @@ public function testRedisWithParametersAndPrefix() 'prefix' => 'test-redis-assertion' ) )); - $predis->addItem('this_is_a_test_key', 'this-is-a-test-value'); - $value = $predis->getItem('this_is_a_test_key'); - $this->assertEquals('this-is-a-test-value', $value->get()); - $result = $predis->deleteItem('this_is_a_test_key'); - $this->assertTrue($result); + $predisClient = new \Predis\Client([ + 'host' => REDIS_HOST, + 'port' => REDIS_PORT, + ]); + $predisClient->set('test-redis-assertion.this_is_a_test_key', 'this-is-a-test-value'); + + $value = $predis->get('this_is_a_test_key'); + $this->assertEquals('this-is-a-test-value', $value); + + $predisClient->del('test-redis-assertion.this_is_a_test_key'); } public function testRedisWithParametersPrefixAndSentinels() @@ -86,11 +96,16 @@ public function testRedisWithParametersPrefixAndSentinels() 'prefix' => 'test-redis-assertion' ) )); - $predis->addItem('this_is_a_test_key', 'this-is-a-test-value'); - $value = $predis->getItem('this_is_a_test_key'); - $this->assertEquals('this-is-a-test-value', $value->get()); - $result = $predis->deleteItem('this_is_a_test_key'); - $this->assertTrue($result); + $predisClient = new \Predis\Client([ + 'host' => REDIS_HOST, + 'port' => REDIS_PORT, + ]); + $predisClient->set('test-redis-assertion.this_is_a_test_key', 'this-is-a-test-value'); + + $value = $predis->get('this_is_a_test_key'); + $this->assertEquals('this-is-a-test-value', $value); + + $predisClient->del('test-redis-assertion.this_is_a_test_key'); } public function testRedisWithEmptySentinels() @@ -217,7 +232,7 @@ public function testRedisWithSentinels() ) )); - $predis->getItem('this_is_a_test_key'); + $predis->get('this_is_a_test_key'); } public function testRedisWithSentinelsAndDistributedStrategy() @@ -233,7 +248,7 @@ public function testRedisWithSentinelsAndDistributedStrategy() ) )); - $predis->getItem('this_is_a_test_key'); + $predis->get('this_is_a_test_key'); } public function testRedisWithEmptyClusters() @@ -307,7 +322,7 @@ public function testRedisWithInvalidKeyHashtagInClusters() ) )); - $predis->getItem('this_is_a_test_key'); + $predis->get('this_is_a_test_key'); } public function testRedisWithInvalidBeginingKeyHashtagInClusters() @@ -327,7 +342,7 @@ public function testRedisWithInvalidBeginingKeyHashtagInClusters() ) )); - $predis->getItem('this_is_a_test_key'); + $predis->get('this_is_a_test_key'); } public function testRedisWithWrongTypeKeyHashtagInClusters() @@ -347,7 +362,7 @@ public function testRedisWithWrongTypeKeyHashtagInClusters() ) )); - $predis->getItem('this_is_a_test_key'); + $predis->get('this_is_a_test_key'); } public function testRedisWithWrongLengthKeyHashtagInClusters() @@ -367,7 +382,7 @@ public function testRedisWithWrongLengthKeyHashtagInClusters() ) )); - $predis->getItem('this_is_a_test_key'); + $predis->get('this_is_a_test_key'); } public function testRedisWithClusters() @@ -383,7 +398,7 @@ public function testRedisWithClusters() ) )); - $predis->getItem('this_is_a_test_key'); + $predis->get('this_is_a_test_key'); } public function testRedisWithoutCustomKeyHashtagClusters() @@ -398,7 +413,7 @@ public function testRedisWithoutCustomKeyHashtagClusters() ) )); - $predis->getItem('this_is_a_test_key'); + $predis->get('this_is_a_test_key'); } public function testRedisWithClustersKeyHashTags() @@ -417,7 +432,7 @@ public function testRedisWithClustersKeyHashTags() ) )); - $predis->getItem('this_is_a_test_key'); + $predis->get('this_is_a_test_key'); } public function testRedisWithClustersKeyHashTagsInvalid() @@ -436,7 +451,7 @@ public function testRedisWithClustersKeyHashTagsInvalid() ) )); - $predis->getItem('this_is_a_test_key'); + $predis->get('this_is_a_test_key'); } public function testRedisWithClustersKeyHashTagsInvalidHashTags() @@ -455,7 +470,7 @@ public function testRedisWithClustersKeyHashTagsInvalidHashTags() ) )); - $predis->getItem('this_is_a_test_key'); + $predis->get('this_is_a_test_key'); } public function testRedisWithClustersKeyHashTagsValid() @@ -471,7 +486,7 @@ public function testRedisWithClustersKeyHashTagsValid() ) )); - $predis->getItem('this_is_a_test_key'); + $predis->get('this_is_a_test_key'); } public function testRedisSSLWithClusterFails() diff --git a/tests/Suite/Attributes/SdkAttributesTest.php b/tests/Suite/Attributes/SdkAttributesTest.php index cb47451e..6b3e050c 100644 --- a/tests/Suite/Attributes/SdkAttributesTest.php +++ b/tests/Suite/Attributes/SdkAttributesTest.php @@ -7,41 +7,10 @@ use SplitIO\Component\Cache\SplitCache; use SplitIO\Component\Common\Di; +use SplitIO\Test\Utils; + class SdkAttributesTest extends \PHPUnit\Framework\TestCase { - private function addSplitsInCache() - { - $splitChanges = file_get_contents(__DIR__."/files/splitChanges.json"); - $this->assertJson($splitChanges); - - $splitCache = new SplitCache(); - - $splitChanges = json_decode($splitChanges, true); - $splits = $splitChanges['splits']; - - foreach ($splits as $split) { - $splitName = $split['name']; - $this->assertTrue($splitCache->addSplit($splitName, json_encode($split))); - } - } - - private function addSegmentsInCache() - { - $segmentCache = new SegmentCache(); - - //Addinng Employees Segment. - $segmentEmployeesChanges = file_get_contents(__DIR__."/files/segmentEmployeesChanges.json"); - $this->assertJson($segmentEmployeesChanges); - $segmentData = json_decode($segmentEmployeesChanges, true); - $this->assertArrayHasKey('employee_1', $segmentCache->addToSegment($segmentData['name'], $segmentData['added'])); - - //Adding Human Beigns Segment. - $segmentHumanBeignsChanges = file_get_contents(__DIR__."/files/segmentHumanBeignsChanges.json"); - $this->assertJson($segmentHumanBeignsChanges); - $segmentData = json_decode($segmentHumanBeignsChanges, true); - $this->assertArrayHasKey('user1', $segmentCache->addToSegment($segmentData['name'], $segmentData['added'])); - } - public function testClient() { Di::set(Di::KEY_FACTORY_TRACKER, false); @@ -50,7 +19,7 @@ public function testClient() $this->assertTrue(is_string(\SplitIO\version())); $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout', 'level' => 'info'), @@ -62,8 +31,9 @@ public function testClient() $splitSdk = $splitFactory->client(); //Populating the cache. - $this->addSplitsInCache(); - $this->addSegmentsInCache(); + Utils\Utils::addSplitsInCache(file_get_contents(__DIR__."/files/splitChanges.json")); + Utils\Utils::addSegmentsInCache(file_get_contents(__DIR__."/files/segmentEmployeesChanges.json")); + Utils\Utils::addSegmentsInCache(file_get_contents(__DIR__."/files/segmentHumanBeignsChanges.json")); //Assertions $this->inOperator($splitSdk); @@ -268,4 +238,9 @@ private function betweenOperator(\SplitIO\Sdk\ClientInterface $splitSdk) $this->assertEquals('off', $splitSdk->getTreatment('user1', 'user_attr_btw_datetime_1458240947021_and_1458246884077', array())); $this->assertEquals('off', $splitSdk->getTreatment('user1', 'user_attr_btw_datetime_1458240947021_and_1458246884077', null)); } + + public static function tearDownAfterClass(): void + { + Utils\Utils::cleanCache(); + } } diff --git a/tests/Suite/Component/KeysStaticMethodsTest.php b/tests/Suite/Component/KeysStaticMethodsTest.php index f1648571..41e9f331 100644 --- a/tests/Suite/Component/KeysStaticMethodsTest.php +++ b/tests/Suite/Component/KeysStaticMethodsTest.php @@ -45,13 +45,6 @@ public function testSplitGetSplitNameFromCacheKey() $this->assertEquals($splitName, 'abc'); } - public function testSegmentGetCacheKeyForRegisterSegments() - { - $method = self::getStaticMethodAsPublic('SplitIO\Component\Cache\SegmentCache', 'getCacheKeyForRegisterSegments'); - $key = $method->invoke(null); - $this->assertEquals($key, 'SPLITIO.segments.registered'); - } - public function testSegmentGetCacheKeyForSegmentData() { $method = self::getStaticMethodAsPublic('SplitIO\Component\Cache\SegmentCache', 'getCacheKeyForSegmentData'); diff --git a/tests/Suite/Component/TrafficTypeTests.php b/tests/Suite/Component/TrafficTypeTests.php index 0665a42f..69e5c781 100644 --- a/tests/Suite/Component/TrafficTypeTests.php +++ b/tests/Suite/Component/TrafficTypeTests.php @@ -25,7 +25,7 @@ private function getMockedLogger() public function testTrafficTypeWarning() { $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), diff --git a/tests/Suite/DynamicConfigurations/EvaluatorTest.php b/tests/Suite/DynamicConfigurations/EvaluatorTest.php index f2927c9c..9bc75489 100644 --- a/tests/Suite/DynamicConfigurations/EvaluatorTest.php +++ b/tests/Suite/DynamicConfigurations/EvaluatorTest.php @@ -61,7 +61,7 @@ class EvaluatorTest extends \PHPUnit\Framework\TestCase public function testSplitWithoutConfigurations() { $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), @@ -89,7 +89,7 @@ public function testSplitWithoutConfigurations() public function testSplitWithConfigurations() { $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), @@ -117,7 +117,7 @@ public function testSplitWithConfigurations() public function testSplitWithConfigurationsButKilled() { $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), @@ -145,7 +145,7 @@ public function testSplitWithConfigurationsButKilled() public function testSplitWithConfigurationsButKilledWithConfigsOnDefault() { $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), diff --git a/tests/Suite/DynamicConfigurations/SplitTest.php b/tests/Suite/DynamicConfigurations/SplitTest.php index 0d560504..44bb0e3b 100644 --- a/tests/Suite/DynamicConfigurations/SplitTest.php +++ b/tests/Suite/DynamicConfigurations/SplitTest.php @@ -35,7 +35,7 @@ class SplitTest extends \PHPUnit\Framework\TestCase public function testSplitWithoutConfigurations() { $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), @@ -65,7 +65,7 @@ public function testSplitWithoutConfigurations() public function testSplitWithConfigurations() { $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), diff --git a/tests/Suite/Engine/HashTest.php b/tests/Suite/Engine/HashTest.php index 72a7685a..a5a73be2 100644 --- a/tests/Suite/Engine/HashTest.php +++ b/tests/Suite/Engine/HashTest.php @@ -8,6 +8,9 @@ use SplitIO\Engine\Hash\HashAlgorithmEnum; use SplitIO\Grammar\Split; use SplitIO\Split as SplitApp; +use SplitIO\Component\Common\Di; + +use SplitIO\Test\Utils; class HashTest extends \PHPUnit\Framework\TestCase { @@ -74,26 +77,12 @@ public function testMurmur3HashFunction() } } - private function addSplitsInCache() - { - $splitChanges = file_get_contents(__DIR__."/../../files/algoSplits.json"); - $this->assertJson($splitChanges); - - $splitCache = new SplitCache(); - - $splitChanges = json_decode($splitChanges, true); - $splits = $splitChanges['splits']; - - foreach ($splits as $split) { - $splitName = $split['name']; - $this->assertTrue($splitCache->addSplit($splitName, json_encode($split))); - } - } - public function testAlgoField() { + Di::set(Di::KEY_FACTORY_TRACKER, false); + $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), @@ -105,7 +94,7 @@ public function testAlgoField() $splitFactory->client(); //Populating the cache. - $this->addSplitsInCache(); + Utils\Utils::addSplitsInCache(file_get_contents(__DIR__."/../../files/algoSplits.json")); $cases = array( array( // Split with algo = 1. Should use legacy function @@ -138,4 +127,9 @@ public function testAlgoField() $this->assertInstanceof($case['class'], $hasher); } } + + public static function tearDownAfterClass(): void + { + Utils\Utils::cleanCache(); + } } diff --git a/tests/Suite/InputValidation/FactoryTrackerTest.php b/tests/Suite/InputValidation/FactoryTrackerTest.php index 92797e54..0a86a281 100644 --- a/tests/Suite/InputValidation/FactoryTrackerTest.php +++ b/tests/Suite/InputValidation/FactoryTrackerTest.php @@ -8,7 +8,7 @@ class FactoryTrackerTest extends \PHPUnit\Framework\TestCase private function getFactoryClient() { $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), diff --git a/tests/Suite/InputValidation/GetTreatmentValidationTest.php b/tests/Suite/InputValidation/GetTreatmentValidationTest.php index 6f6cca54..b81c8dc1 100644 --- a/tests/Suite/InputValidation/GetTreatmentValidationTest.php +++ b/tests/Suite/InputValidation/GetTreatmentValidationTest.php @@ -4,13 +4,15 @@ use SplitIO\Component\Common\Di; use SplitIO\Sdk\Key; +use SplitIO\Test\Utils; + class GetTreatmentValidationTest extends \PHPUnit\Framework\TestCase { private function getFactoryClient() { Di::set(Di::KEY_FACTORY_TRACKER, false); $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), @@ -363,4 +365,9 @@ public function testGetTreatmentWithConfigWithNotExistantSplitName() $result = $splitSdk->getTreatmentWithConfig('some_key_non_existant', 'some_feature_non_existant'); $this->assertEquals('control', $result['treatment']); } + + public static function tearDownAfterClass(): void + { + Utils\Utils::cleanCache(); + } } diff --git a/tests/Suite/InputValidation/GetTreatmentsValidationTest.php b/tests/Suite/InputValidation/GetTreatmentsValidationTest.php index 04ac1c1d..ac552efb 100644 --- a/tests/Suite/InputValidation/GetTreatmentsValidationTest.php +++ b/tests/Suite/InputValidation/GetTreatmentsValidationTest.php @@ -4,13 +4,15 @@ use SplitIO\Component\Common\Di; use SplitIO\Sdk\Key; +use SplitIO\Test\Utils; + class GetTreatmentsValidationTest extends \PHPUnit\Framework\TestCase { private function getFactoryClient() { Di::set(Di::KEY_FACTORY_TRACKER, false); $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), @@ -404,4 +406,9 @@ public function testGetTreatmenstConfigWithoutExistingFeatureName() $this->assertEquals('control', $treatmentResult['some_feature_non_existant']['treatment']); } + + public static function tearDownAfterClass(): void + { + Utils\Utils::cleanCache(); + } } diff --git a/tests/Suite/InputValidation/ManagerValidationTest.php b/tests/Suite/InputValidation/ManagerValidationTest.php index dbab8dd3..77ef7bb9 100644 --- a/tests/Suite/InputValidation/ManagerValidationTest.php +++ b/tests/Suite/InputValidation/ManagerValidationTest.php @@ -9,7 +9,7 @@ private function getFactoryClient() { Di::set(Di::KEY_FACTORY_TRACKER, false); $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), diff --git a/tests/Suite/InputValidation/TrackValidationTest.php b/tests/Suite/InputValidation/TrackValidationTest.php index bdd58614..e42bb603 100644 --- a/tests/Suite/InputValidation/TrackValidationTest.php +++ b/tests/Suite/InputValidation/TrackValidationTest.php @@ -4,13 +4,15 @@ use SplitIO\Component\Common\Di; use SplitIO\Sdk\Validator\InputValidator; +use SplitIO\Test\Utils; + class TrackValidationTest extends \PHPUnit\Framework\TestCase { private function getFactoryClient() { Di::set(Di::KEY_FACTORY_TRACKER, false); $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), @@ -513,4 +515,9 @@ public function testTrackWithEventGreaterThan32KB() $this->assertEquals(false, $splitSdk->track('some_key', 'some_traffic', 'some_event', 1, $properties)); } + + public static function tearDownAfterClass(): void + { + Utils\Utils::cleanCache(); + } } diff --git a/tests/Suite/Matchers/MatchersTest.php b/tests/Suite/Matchers/MatchersTest.php index 7c3dffdc..6b85b0dc 100644 --- a/tests/Suite/Matchers/MatchersTest.php +++ b/tests/Suite/Matchers/MatchersTest.php @@ -10,6 +10,8 @@ use SplitIO\Component\Common\Di; use \ReflectionMethod; +use SplitIO\Test\Utils; + class MatcherTest extends \PHPUnit\Framework\TestCase { private function setupSplitApp() @@ -21,7 +23,7 @@ private function setupSplitApp() 'port' => 6379, 'timeout' => 881 ); - $options = array('prefix' => ''); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout', 'level' => 'info'), 'cache' => array('adapter' => 'predis', @@ -36,9 +38,14 @@ private function setupSplitApp() private function populateSegmentCache() { - SegmentCache::registerSegment('segmentA'); - $segmentCache = new SegmentCache(); - $segmentCache->addToSegment('segmentA', array('id1', 'id2', 'id3')); + $segmentKey = "SPLITIO.segment."; + + $predis = new \Predis\Client([ + 'host' => REDIS_HOST, + 'port' => REDIS_PORT, + ], ['prefix' => TEST_PREFIX]); + + $predis->sadd($segmentKey . 'segmentA', array('id1', 'id2', 'id3')); } public function testSartsWithMatcher() @@ -493,4 +500,9 @@ public function testBooleanMatcher() $matcher2 = new Matcher\EqualToBoolean(false); $this->assertEquals($meth->invoke($matcher2, 'ff'), false); } + + public static function tearDownAfterClass(): void + { + Utils\Utils::cleanCache(); + } } diff --git a/tests/Suite/Redis/CacheInterfacesTest.php b/tests/Suite/Redis/CacheInterfacesTest.php index f7130a2b..75f10b8e 100644 --- a/tests/Suite/Redis/CacheInterfacesTest.php +++ b/tests/Suite/Redis/CacheInterfacesTest.php @@ -10,6 +10,11 @@ use SplitIO\Component\Log\Handler\Stdout; use SplitIO\Component\Log\Logger; use SplitIO\Component\Log\LogLevelEnum; +use SplitIO\Sdk\Events\EventDTO; +use SplitIO\Sdk\Events\EventQueueMessage; +use SplitIO\Sdk\QueueMetadataMessage; + +use SplitIO\Test\Utils; class CacheInterfacesTest extends \PHPUnit\Framework\TestCase { @@ -31,18 +36,21 @@ public function testDiLog() public function testDiCache() { try { - $cachePoolAdapter = array( - 'name' => 'redis', - 'options' => array( - 'host' => REDIS_HOST, - 'port' => REDIS_PORT, - ) + $parameters = array( + 'host' => REDIS_HOST, + 'port' => REDIS_PORT, ); - $cachePool = new Pool(array( 'adapter' => $cachePoolAdapter )); + $cachePool = new Pool(array('adapter' => array( + 'name' => 'predis', + 'options' => array( + 'options' => array('prefix' => TEST_PREFIX), + 'parameters' => $parameters, + ), + ))); Di::getInstance()->setCache($cachePool); } catch (\Exception $e) { - $this->assertTrue(false, "Error setting cache on Di"); + $this->assertTrue(false, "Error setting cache on Di". $e); } $this->assertTrue(true); @@ -57,6 +65,7 @@ public function testSplitCacheInterface() $splitChanges = file_get_contents(__DIR__."/../../files/splitChanges.json"); $this->assertJson($splitChanges); + Utils\Utils::addSplitsInCache($splitChanges); $splitCache = new SplitCache(); $splitChanges = json_decode($splitChanges, true); @@ -65,14 +74,7 @@ public function testSplitCacheInterface() $splitName = $split['name']; - $this->assertTrue($splitCache->addSplit($splitName, json_encode($split))); - $this->assertEquals(strlen(json_encode($split)), strlen($splitCache->getSplit($splitName))); - - $this->assertTrue($splitCache->removeSplit($splitName)); - - $this->assertTrue($splitCache->setChangeNumber($splitChanges['till'])); - $this->assertEquals($splitChanges['till'], $splitCache->getChangeNumber()); } @@ -82,48 +84,19 @@ public function testSplitCacheInterface() public function testSegmentCacheInterface() { $segmentChanges = file_get_contents(__DIR__."/../../files/segmentEmployeesChanges.json"); - $this->assertJson($segmentChanges); - $segmentData = json_decode($segmentChanges, true); + Utils\Utils::addSegmentsInCache($segmentChanges); + $segmentData = json_decode($segmentChanges, true); $segmentName = $segmentData['name']; - $segmentCache = new SegmentCache(); - - $this->assertArrayHasKey('fake_user_id_4', $segmentCache->addToSegment($segmentName, $segmentData['added'])); - - $removedResult = $segmentCache->removeFromSegment($segmentName, $segmentData['removed']); - $this->assertArrayHasKey('fake_user_id_6', $removedResult); - - $this->assertTrue($segmentCache->setChangeNumber($segmentName, $segmentData['till'])); + $this->assertTrue(boolval($segmentCache->isInSegment($segmentName, "fake_user_id_4"))); + $this->assertFalse(boolval($segmentCache->isInSegment($segmentName, "fake_user_id_4_"))); $this->assertEquals($segmentData['till'], $segmentCache->getChangeNumber($segmentName)); } - /** - * @depends testDiLog - * @depends testDiCache - */ - public function testBlockUntilReadyCacheInterface() - { - $dateTimeUTC = new \DateTime("now", new \DateTimeZone("UTC")); - $deltaTime = 100; - - $splitsTimestamp = $dateTimeUTC->getTimestamp(); - $segmentsTimestamp = $dateTimeUTC->getTimestamp() + $deltaTime; - - $bur = new BlockUntilReadyCache(); - $bur->setReadySplits($splitsTimestamp); - $bur->setReadySegments($segmentsTimestamp); - - //Checking - $this->assertEquals($splitsTimestamp, $bur->getReadySplits()); - $this->assertEquals($segmentsTimestamp, $bur->getReadySegments()); - - $this->assertEquals(min($splitsTimestamp, $segmentsTimestamp), $bur->getReadyCheckpoint()); - } - /** * @depends testDiLog * @depends testDiCache @@ -135,9 +108,8 @@ public function testEventsCache() $eventType = "some_event_type"; $value = 0.0; - $eventDTO = new EventDTO($key, $trafficType, $eventType, $value); - $eventMessageMetadata = new EventQueueMetadataMessage(); - $eventQueueMessage = new EventQueueMessage($eventMessageMetadata, $eventDTO); + $eventDTO = new EventDTO($key, $trafficType, $eventType, $value, null); + $eventQueueMessage = new EventQueueMessage(new QueueMetadataMessage(), $eventDTO); $this->assertTrue(EventsCache::addEvent($eventQueueMessage)); } @@ -160,8 +132,7 @@ public function testEventsCacheWithProperties() ); $eventDTO = new EventDTO($key, $trafficType, $eventType, $value, $properties); - $eventMessageMetadata = new EventQueueMetadataMessage(); - $eventQueueMessage = new EventQueueMessage($eventMessageMetadata, $eventDTO); + $eventQueueMessage = new EventQueueMessage(new QueueMetadataMessage(), $eventDTO); $this->assertTrue(EventsCache::addEvent($eventQueueMessage)); diff --git a/tests/Suite/Redis/PRedisReadOnlyMock.php b/tests/Suite/Redis/PRedisReadOnlyMock.php index 526bd10d..3e859f11 100644 --- a/tests/Suite/Redis/PRedisReadOnlyMock.php +++ b/tests/Suite/Redis/PRedisReadOnlyMock.php @@ -14,13 +14,13 @@ public function __construct(PRedis $predis) } - /** + /** * @param string $key - * @return \SplitIO\Component\Cache\Item + * @return string */ - public function getItem($key) + public function get($key) { - return $this->predis->getItem($key); + return $this->predis->get($key); } /** @@ -39,80 +39,9 @@ public function getItem($key) * key is not found. However, if no keys are specified then an empty * traversable MUST be returned instead. */ - public function getItems(array $keys = array()) - { - return $this->predis->getItems($keys); - } - - /** - * @param string $key - * @param mixed $value - * @param int|null $expiration - * @return bool - */ - public function addItem($key, $value, $expiration = null) - { - throw new \Exception('READONLY mode mocked.'); - } - - /** - * @return bool - */ - public function clear() - { - throw new \Exception('READONLY mode mocked.'); - } - - /** - * @param $key - * @return bool - */ - public function deleteItem($key) - { - throw new \Exception('READONLY mode mocked.'); - } - - /** - * @param array $keys - * @return bool - */ - public function deleteItems(array $keys) + public function fetchMany(array $keys = array()) { - throw new \Exception('READONLY mode mocked.'); - } - - /** - * @param $key - * @param $value - * @param int|null $expiration - * @return bool - */ - public function save($key, $value, $expiration = null) - { - throw new \Exception('READONLY mode mocked.'); - } - - /** - * Adds a values to the set value stored at key. - * If this value is already in the set, FALSE is returned. - * - * @param $key - * @param $value - * @return boolean - */ - public function addItemList($key, $value) - { - throw new \Exception('READONLY mode mocked.'); - } - - /** - * @param $key - * @param $value - * @return mixed - */ - public function removeItemList($key, $value) - { - throw new \Exception('READONLY mode mocked.'); + return $this->predis->fetchMany($keys); } /** @@ -125,45 +54,16 @@ public function isOnList($key, $value) return $this->predis->isOnList($key, $value); } - /** - * @param $key - * @return mixed - */ - public function getListItems($key) - { - return $this->predis->getListItems($key); - } - - public function getListItemsRandomly($key, $count) - { - return $this->predis->getListItemsRandomly($key, $count); - } - public function getKeys($pattern = '*') { return $this->predis->getKeys($pattern); } - public function incrementKey($key) - { - throw new \Exception('READONLY mode mocked.'); - } - - public function getSet($key, $value) - { - return $this->predis->getSet($key, $value); - } - private function normalizePrefix($prefix) { return $this->predis->normalizePrefix($prefix); } - public function saveItemOnList($key, $value) - { - throw new \Exception('READONLY mode mocked.'); - } - public function rightPushInList($key, $value) { throw new \Exception('READONLY mode mocked.'); diff --git a/tests/Suite/Redis/ReflectiveTools.php b/tests/Suite/Redis/ReflectiveTools.php index 870c2ed4..675cec3c 100644 --- a/tests/Suite/Redis/ReflectiveTools.php +++ b/tests/Suite/Redis/ReflectiveTools.php @@ -13,6 +13,11 @@ public static function clientFromCachePool(\SplitIO\Component\Cache\Pool $cacheP $reflectionAdapter->setAccessible(true); $adapter = $reflectionAdapter->getValue($cachePool); + $reflectionSafeRedis = new ReflectionClass('SplitIO\Component\Cache\Storage\Adapter\SafeRedisWrapper'); + $reflectionCacheAdapter= $reflectionSafeRedis->getProperty('cacheAdapter'); + $reflectionCacheAdapter->setAccessible(true); + $adapter = $reflectionCacheAdapter->getValue($adapter); + $reflectionPRedis = new ReflectionClass('SplitIO\Component\Cache\Storage\Adapter\PRedis'); $reflectionClient= $reflectionPRedis->getProperty('client'); $reflectionClient->setAccessible(true); diff --git a/tests/Suite/Redis/SafeRedisWrapperTest.php b/tests/Suite/Redis/SafeRedisWrapperTest.php new file mode 100644 index 00000000..473a7aa6 --- /dev/null +++ b/tests/Suite/Redis/SafeRedisWrapperTest.php @@ -0,0 +1,50 @@ +getMockBuilder('\Predis\Client') + ->disableOriginalConstructor() + ->setMethods($cachePoolMethods) + ->getMock(); + + foreach ($cachePoolMethods as $method) { + $predisMock->method($method) + ->will($this->throwException(new \Exception())); + } + + $predisMock->method('getOptions') + ->willReturn(array()); + + $predisAdapter = new PRedis(array( + 'parameters' => array( + 'scheme' => 'tcp', + 'host' => 'localhost', + 'port' => 6379, + ) + )); + $refObject = new \ReflectionObject($predisAdapter); + $refProperty = $refObject->getProperty('client'); + $refProperty->setAccessible(true); + $refProperty->setValue($predisAdapter, $predisMock); + $safeRedisWrapper = new SafeRedisWrapper($predisAdapter); + + $this->assertEquals(false, $safeRedisWrapper->get("some")); + $this->assertEquals(array(), $safeRedisWrapper->fetchMany(array("some"))); + $this->assertEquals(false, $safeRedisWrapper->isOnList("some", "another")); + $this->assertEquals(array(), $safeRedisWrapper->getKeys("some")); + $this->assertEquals(0, $safeRedisWrapper->rightPushQueue("some", "another")); + $this->assertEquals(false, $safeRedisWrapper->expireKey("some", 12345)); + } +} diff --git a/tests/Suite/Sdk/ImpressionWrapperTest.php b/tests/Suite/Sdk/ImpressionWrapperTest.php index ab9fa17e..10d45d83 100644 --- a/tests/Suite/Sdk/ImpressionWrapperTest.php +++ b/tests/Suite/Sdk/ImpressionWrapperTest.php @@ -10,24 +10,10 @@ use SplitIO\Test\Suite\Sdk\Helpers\ListenerClientWrong; use SplitIO\Component\Common\Di; +use SplitIO\Test\Utils; + class ImpressionListenerTest extends \PHPUnit\Framework\TestCase { - private function addSplitsInCache() - { - $splitChanges = file_get_contents(__DIR__."/files/splitil.json"); - $this->assertJson($splitChanges); - - $splitCache = new SplitCache(); - - $splitChanges = json_decode($splitChanges, true); - $splits = $splitChanges['splits']; - - foreach ($splits as $split) { - $splitName = $split['name']; - $this->assertTrue($splitCache->addSplit($splitName, json_encode($split))); - } - } - public function testSendDataToClient() { $impression = new Impression( @@ -77,7 +63,7 @@ private function getFactoryClient($sdkConfig) public function testClientThrowningExceptionInListener() { $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $impressionClient = new ListenerClientWithException(); @@ -91,7 +77,7 @@ public function testClientThrowningExceptionInListener() $splitSdk = $this->getFactoryClient($sdkConfig); //Populating the cache. - $this->addSplitsInCache(); + Utils\Utils::addSplitsInCache(file_get_contents(__DIR__."/files/splitil.json")); //Assertions $this->assertEquals('on', $splitSdk->getTreatment('valid', 'iltest')); @@ -100,7 +86,7 @@ public function testClientThrowningExceptionInListener() public function testClientWithNullIpAddress() { $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $impressionClient2 = new ListenerClient(); @@ -114,7 +100,7 @@ public function testClientWithNullIpAddress() $splitSdk = $this->getFactoryClient($sdkConfig); //Populating the cache. - $this->addSplitsInCache(); + Utils\Utils::addSplitsInCache(file_get_contents(__DIR__."/files/splitil.json")); //Assertions $this->assertEquals('on', $splitSdk->getTreatment('valid', 'iltest')); @@ -131,7 +117,7 @@ public function testClientWithNullIpAddress() public function testClient() { $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $impressionClient = new ListenerClient(); @@ -146,7 +132,7 @@ public function testClient() $splitSdk = $this->getFactoryClient($sdkConfig); //Populating the cache. - $this->addSplitsInCache(); + Utils\Utils::addSplitsInCache(file_get_contents(__DIR__."/files/splitil.json")); //Assertions $this->assertEquals('on', $splitSdk->getTreatment('valid', 'iltest')); @@ -172,7 +158,7 @@ public function testClient() public function testClientWithEmptyIpAddress() { $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $impressionClient3 = new ListenerClient(); @@ -187,7 +173,7 @@ public function testClientWithEmptyIpAddress() $splitSdk = $this->getFactoryClient($sdkConfig); //Populating the cache. - $this->addSplitsInCache(); + Utils\Utils::addSplitsInCache(file_get_contents(__DIR__."/files/splitil.json")); //Assertions $this->assertEquals('on', $splitSdk->getTreatment('valid', 'iltest')); @@ -204,7 +190,7 @@ public function testClientWithEmptyIpAddress() public function testClientWithEmptyStringIpAddress() { $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $impressionClient4 = new ListenerClient(); @@ -219,7 +205,7 @@ public function testClientWithEmptyStringIpAddress() $splitSdk = $this->getFactoryClient($sdkConfig); //Populating the cache. - $this->addSplitsInCache(); + Utils\Utils::addSplitsInCache(file_get_contents(__DIR__."/files/splitil.json")); //Assertions $this->assertEquals('on', $splitSdk->getTreatment('valid', 'iltest')); @@ -236,7 +222,7 @@ public function testClientWithEmptyStringIpAddress() public function testClientErasingServer() { $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $impressionClient4 = new ListenerClient(); @@ -252,7 +238,7 @@ public function testClientErasingServer() $splitSdk = $this->getFactoryClient($sdkConfig); //Populating the cache. - $this->addSplitsInCache(); + Utils\Utils::addSplitsInCache(file_get_contents(__DIR__."/files/splitil.json")); //Assertions $this->assertEquals('on', $splitSdk->getTreatment('valid', 'iltest')); @@ -269,7 +255,7 @@ public function testClientErasingServer() public function testClientWithoutImpressionListener() { $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $impressionClient5 = new ListenerClient(); @@ -282,7 +268,7 @@ public function testClientWithoutImpressionListener() $splitSdk = $this->getFactoryClient($sdkConfig); //Populating the cache. - $this->addSplitsInCache(); + Utils\Utils::addSplitsInCache(file_get_contents(__DIR__."/files/splitil.json")); //Assertions $this->assertEquals('on', $splitSdk->getTreatment('valid', 'iltest')); @@ -291,7 +277,7 @@ public function testClientWithoutImpressionListener() public function testClientWithNullImpressionListener() { $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $impressionClient6 = new ListenerClient(); @@ -305,9 +291,14 @@ public function testClientWithNullImpressionListener() $splitSdk = $this->getFactoryClient($sdkConfig); //Populating the cache. - $this->addSplitsInCache(); + Utils\Utils::addSplitsInCache(file_get_contents(__DIR__."/files/splitil.json")); //Assertions $this->assertEquals('on', $splitSdk->getTreatment('valid', 'iltest')); } + + public static function tearDownAfterClass(): void + { + Utils\Utils::cleanCache(); + } } diff --git a/tests/Suite/Sdk/ImpressionsTest.php b/tests/Suite/Sdk/ImpressionsTest.php index c717b8cf..0ba34dc1 100644 --- a/tests/Suite/Sdk/ImpressionsTest.php +++ b/tests/Suite/Sdk/ImpressionsTest.php @@ -8,13 +8,15 @@ use SplitIO\Component\Cache\ImpressionCache; use SplitIO\Sdk\QueueMetadataMessage; +use SplitIO\Test\Utils; + class ImpressionsTest extends \PHPUnit\Framework\TestCase { public function testImpressionsAreAdded() { Di::set(Di::KEY_FACTORY_TRACKER, false); $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), @@ -63,7 +65,7 @@ public function testExpirationOnlyOccursOnce() { Di::set(Di::KEY_FACTORY_TRACKER, false); $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), @@ -119,4 +121,9 @@ public function testExpirationOnlyOccursOnce() $this->assertEquals($decoded['i']['m'], 123456); $this->assertEquals($decoded['i']['c'], 321654); } + + public static function tearDownAfterClass(): void + { + Utils\Utils::cleanCache(); + } } diff --git a/tests/Suite/Sdk/SdkClientTest.php b/tests/Suite/Sdk/SdkClientTest.php index a82f3d89..80da42cd 100644 --- a/tests/Suite/Sdk/SdkClientTest.php +++ b/tests/Suite/Sdk/SdkClientTest.php @@ -14,44 +14,10 @@ use SplitIO\Component\Cache\SplitCache; use SplitIO\Sdk\Client; +use SplitIO\Test\Utils; + class SdkClientTest extends \PHPUnit\Framework\TestCase { - private function addSplitsInCache() - { - $splitChanges = file_get_contents(__DIR__."/files/splitChanges.json"); - $this->assertJson($splitChanges); - - $splitCache = new SplitCache(); - - $splitChanges = json_decode($splitChanges, true); - $splits = $splitChanges['splits']; - - foreach ($splits as $split) { - $splitName = $split['name']; - $this->assertTrue($splitCache->addSplit($splitName, json_encode($split))); - } - } - - private function addSegmentsInCache() - { - $segmentCache = new SegmentCache(); - - //Addinng Employees Segment. - $segmentEmployeesChanges = file_get_contents(__DIR__ . "/files/segmentEmployeesChanges.json"); - $this->assertJson($segmentEmployeesChanges); - $segmentData = json_decode($segmentEmployeesChanges, true); - $this->assertArrayHasKey('employee_1', $segmentCache->addToSegment( - $segmentData['name'], - $segmentData['added'] - )); - - //Adding Human Beigns Segment. - $segmentHumanBeignsChanges = file_get_contents(__DIR__."/files/segmentHumanBeignsChanges.json"); - $this->assertJson($segmentHumanBeignsChanges); - $segmentData = json_decode($segmentHumanBeignsChanges, true); - $this->assertArrayHasKey('user1', $segmentCache->addToSegment($segmentData['name'], $segmentData['added'])); - } - public function testLocalClient() { Di::set(Di::KEY_FACTORY_TRACKER, false); @@ -219,7 +185,6 @@ private function validateLastImpression( ) { $raw = $redisClient->rpop(ImpressionCache::IMPRESSIONS_QUEUE_KEY); $parsed = json_decode($raw, true); - echo "parsed " . json_encode($parsed) . "\n"; $this->assertEquals($parsed['i']['f'], $feature); $this->assertEquals($parsed['i']['k'], $key); $this->assertEquals($parsed['i']['t'], $treatment); @@ -239,7 +204,7 @@ public function testClient() 'port' => REDIS_PORT, 'timeout' => 881, ); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), @@ -252,8 +217,9 @@ public function testClient() $splitManager = $splitFactory->manager(); //Populating the cache. - $this->addSplitsInCache(); - $this->addSegmentsInCache(); + Utils\Utils::addSplitsInCache(file_get_contents(__DIR__."/files/splitChanges.json")); + Utils\Utils::addSegmentsInCache(file_get_contents(__DIR__."/files/segmentEmployeesChanges.json")); + Utils\Utils::addSegmentsInCache(file_get_contents(__DIR__."/files/segmentHumanBeignsChanges.json")); $redisClient = ReflectiveTools::clientFromCachePool(Di::getCache()); @@ -465,7 +431,7 @@ public function testCustomLog() $log->pushHandler(new ErrorLogHandler(ErrorLogHandler::OPERATING_SYSTEM, Logger::INFO)); $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('psr3-instance' => $log), @@ -476,8 +442,9 @@ public function testCustomLog() $splitSdk = $splitFactory->client(); //Populating the cache. - $this->addSplitsInCache(); - $this->addSegmentsInCache(); + Utils\Utils::addSplitsInCache(file_get_contents(__DIR__."/files/splitChanges.json")); + Utils\Utils::addSegmentsInCache(file_get_contents(__DIR__."/files/segmentEmployeesChanges.json")); + Utils\Utils::addSegmentsInCache(file_get_contents(__DIR__."/files/segmentHumanBeignsChanges.json")); //Assertions $this->assertEquals('on', $splitSdk->getTreatment('user1', 'sample_feature')); @@ -520,10 +487,7 @@ public function testCacheExceptionReturnsControl() $splitSdk = $splitFactory->client(); $cachePoolMethods = array( - 'getItem', 'getItems', 'hasItem', 'clear', 'deleteItem', 'deleteItems', - 'save', 'saveDeferred', 'commit', 'saveItemOnList', 'removeItemOnList', - 'getItemOnList', 'getItemsOnList', 'isItemOnList', 'getItemsRandomlyOnList', - 'getKeys', 'incrementeKey', 'getSet', 'rightPushInList' + 'get', 'fetchMany', 'isItemOnList', 'getKeys', 'rightPushInList', 'expireKey' ); $cachePool = $this ->getMockBuilder('\SplitIO\Component\Cache\Pool') @@ -549,7 +513,7 @@ public function testGetTreatmentsWithDistinctFeatures() $this->assertTrue(is_string(\SplitIO\version())); $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), @@ -562,8 +526,9 @@ public function testGetTreatmentsWithDistinctFeatures() $splitSdk = $splitFactory->client(); //Populating the cache. - $this->addSplitsInCache(); - $this->addSegmentsInCache(); + Utils\Utils::addSplitsInCache(file_get_contents(__DIR__."/files/splitChanges.json")); + Utils\Utils::addSegmentsInCache(file_get_contents(__DIR__."/files/segmentEmployeesChanges.json")); + Utils\Utils::addSegmentsInCache(file_get_contents(__DIR__."/files/segmentHumanBeignsChanges.json")); $treatmentResult = $splitSdk->getTreatments('user1', array('sample_feature', 'invalid_feature'), null); @@ -586,7 +551,7 @@ public function testGetTreatmentsWithRepeteadedFeatures() $this->assertTrue(is_string(\SplitIO\version())); $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), @@ -599,8 +564,9 @@ public function testGetTreatmentsWithRepeteadedFeatures() $splitSdk = $splitFactory->client(); //Populating the cache. - $this->addSplitsInCache(); - $this->addSegmentsInCache(); + Utils\Utils::addSplitsInCache(file_get_contents(__DIR__."/files/splitChanges.json")); + Utils\Utils::addSegmentsInCache(file_get_contents(__DIR__."/files/segmentEmployeesChanges.json")); + Utils\Utils::addSegmentsInCache(file_get_contents(__DIR__."/files/segmentHumanBeignsChanges.json")); $treatmentResult = $splitSdk->getTreatments('user1', array('sample_feature', 'invalid_feature', 'sample_feature', 'sample_feature'), null); @@ -625,7 +591,7 @@ public function testGetTreatmentsWithRepeteadedAndNullFeatures() $this->assertTrue(is_string(\SplitIO\version())); $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), @@ -637,8 +603,9 @@ public function testGetTreatmentsWithRepeteadedAndNullFeatures() $splitSdk = $splitFactory->client(); //Populating the cache. - $this->addSplitsInCache(); - $this->addSegmentsInCache(); + Utils\Utils::addSplitsInCache(file_get_contents(__DIR__."/files/splitChanges.json")); + Utils\Utils::addSegmentsInCache(file_get_contents(__DIR__."/files/segmentEmployeesChanges.json")); + Utils\Utils::addSegmentsInCache(file_get_contents(__DIR__."/files/segmentHumanBeignsChanges.json")); $treatmentResult = $splitSdk->getTreatments('user1', array('sample_feature', null, 'invalid_feature', 'sample_feature', null, 'sample_feature'), null); @@ -692,4 +659,9 @@ public function testGetTreatmentsFetchesSplitsInOneCall() $client = new Client(); $client->getTreatments('key1', array('split1', 'split2', 'split3')); } + + public static function tearDownAfterClass(): void + { + Utils\Utils::cleanCache(); + } } diff --git a/tests/Suite/Sdk/SdkReadOnlyTest.php b/tests/Suite/Sdk/SdkReadOnlyTest.php index 63b1c1fe..4eecef8a 100644 --- a/tests/Suite/Sdk/SdkReadOnlyTest.php +++ b/tests/Suite/Sdk/SdkReadOnlyTest.php @@ -11,27 +11,16 @@ use SplitIO\Sdk\Impressions\Impression; use SplitIO\Sdk\QueueMetadataMessage; +use SplitIO\Test\Utils; + class SdkReadOnlyTest extends \PHPUnit\Framework\TestCase { - private function addSplitsInCache() - { - $splitChanges = file_get_contents(__DIR__."/files/splitReadOnly.json"); - $this->assertJson($splitChanges); - $splitCache = new SplitCache(); - $splitChanges = json_decode($splitChanges, true); - $splits = $splitChanges['splits']; - foreach ($splits as $split) { - $splitName = $split['name']; - $this->assertTrue($splitCache->addSplit($splitName, json_encode($split))); - } - } - public function testClient() { Di::set(Di::KEY_FACTORY_TRACKER, false); $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), 'cache' => array('adapter' => 'predis', 'parameters' => $parameters, 'options' => $options) @@ -42,7 +31,7 @@ public function testClient() $splitSdk = $splitFactory->client(); //Populating the cache. - $this->addSplitsInCache(); + Utils\Utils::addSplitsInCache(file_get_contents(__DIR__."/files/splitReadOnly.json")); //Instantiate PRedis Mocked Cache $predis = new PRedis(array('adapter' => 'predis', 'parameters' => $parameters, 'options' => $options)); @@ -77,7 +66,7 @@ public function testException() Di::set(Di::KEY_FACTORY_TRACKER, false); $parameters = array('scheme' => 'redis', 'host' => REDIS_HOST, 'port' => REDIS_PORT, 'timeout' => 881); - $options = array(); + $options = array('prefix' => TEST_PREFIX); $sdkConfig = array( 'log' => array('adapter' => 'stdout'), 'cache' => array('adapter' => 'predis', 'parameters' => $parameters, 'options' => $options) @@ -87,7 +76,7 @@ public function testException() \SplitIO\Sdk::factory('asdqwe123456', $sdkConfig); //Populating the cache. - $this->addSplitsInCache(); + Utils\Utils::addSplitsInCache(file_get_contents(__DIR__."/files/splitReadOnly.json")); //Instantiate PRedis Mocked Cache $predis = new PRedis(array('adapter' => 'predis', 'parameters' => $parameters, 'options' => $options)); @@ -128,4 +117,9 @@ public function testException() TreatmentImpression::log($impression, new QueueMetadataMessage()); } + + public static function tearDownAfterClass(): void + { + Utils\Utils::cleanCache(); + } } diff --git a/tests/Utils/Utils.php b/tests/Utils/Utils.php new file mode 100644 index 00000000..e2be6ec3 --- /dev/null +++ b/tests/Utils/Utils.php @@ -0,0 +1,67 @@ + REDIS_HOST, + 'port' => REDIS_PORT, + ], ['prefix' => TEST_PREFIX]); + + if (is_null($splitChanges)) { + return false; + } + + $splitChanges = json_decode($splitChanges, true); + $splits = $splitChanges['splits']; + + foreach ($splits as $split) { + $splitName = $split['name']; + $predis->set($splitKey . $splitName, json_encode($split)); + } + $till = -1; + if (isset($splitChanges['till'])) { + $till = $splitChanges['till']; + } + $predis->set($tillKey, $till); + return true; + } + + public static function addSegmentsInCache($segmentChanges) + { + $segmentKey = "SPLITIO.segment."; + + $predis = new \Predis\Client([ + 'host' => REDIS_HOST, + 'port' => REDIS_PORT, + ], ['prefix' => TEST_PREFIX]); + + if (is_null($segmentChanges)) { + return false; + } + + $segmentData = json_decode($segmentChanges, true); + $predis->sadd($segmentKey . $segmentData['name'], $segmentData['added']); + $predis->set($segmentKey . $segmentData['name'] . ".till", $segmentData['till']); + + return true; + } + + public static function cleanCache() + { + $predis = new \Predis\Client([ + 'host' => REDIS_HOST, + 'port' => REDIS_PORT, + ]); + + $keys = $predis->keys(TEST_PREFIX . "*"); + foreach ($keys as $key) { + $predis->del($key); + } + } +}