Commit 1e6d7885 authored by Ludwig Ruderstaller's avatar Ludwig Ruderstaller
Browse files

Missing Endpoints and Performance Tests

parent 62fe73a5
Pipeline #17929 passed with stage
in 4 minutes and 2 seconds
......@@ -22,7 +22,7 @@ variables:
#- vendor/bin/php-cs-fixer fix --dry-run --config=.php_cs
# - php -d zend.enable_gc=0 bin/phpunit -c ./phpunit.xml.dist --coverage-html=build/coverage --coverage-xml=build/logs/coverage --log-junit=build/logs/phpunit.xml --coverage-text --colors=never
#- bin/behat --format=progress --verbose --stop-on-failure
- vendor/bin/phpunit --coverage-html build/coverage --log-junit=build/logs/phpunit.xml --coverage-text --colors=never
- vendor/bin/phpunit --coverage-html build/coverage --exclude-group performance --log-junit=build/logs/phpunit.xml --coverage-text --colors=never
stage: test
cache:
key: "${CI_PROJECT_PATH_SLUG}-cache"
......
......@@ -15,7 +15,6 @@ namespace Cwd\PowerDNSClient;
use Doctrine\Common\Annotations\AnnotationReader;
use GuzzleHttp\Psr7\Request;
use Http\Client\HttpClient;
use Http\Discovery\HttpClientDiscovery;
use Symfony\Component\PropertyAccess\PropertyAccessor;
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
......@@ -37,7 +36,7 @@ class Client
private $apiUri;
/** @var HttpClient */
/** @var GuzzleClient */
private $client;
/** @var Serializer */
......@@ -45,11 +44,12 @@ class Client
public function __construct($apiHost, $apiKey, ?GuzzleClient $client = null)
{
$this->apiKey = $apiKey;
$this->apiUri = sprintf('%s/%s', $apiHost, $this->basePath);
if (null === $client) {
//$this->client = new GuzzleClient(['base_uri' => $this->apiUri]);
$this->client = HttpClientDiscovery::find();
}
$this->apiKey = $apiKey;
$this->apiUri = sprintf('%s/%s', $apiHost, $this->basePath);
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$discriminator = new ClassDiscriminatorFromClassMetadata($classMetadataFactory);
......@@ -73,12 +73,11 @@ class Client
*/
public function call($payload = null, $uri, $hydrationClass = null, $isList = false, $method = 'GET', array $queryParams = [])
{
$uri = rtrim(sprintf('%s/%s', $this->apiUri, $uri), '/');
if (count($queryParams) > 0) {
$uri = sprintf('%s/%s?%s', $this->apiUri, $uri, http_build_query($queryParams));
} else {
$uri = sprintf('%s/%s', $this->apiUri, $uri);
$uri .= '?'.http_build_query($queryParams);
}
$uri = rtrim($uri, '/');
$request = new Request($method, $uri, [
'X-API-Key' => $this->apiKey,
......@@ -86,19 +85,22 @@ class Client
], $payload);
$response = $this->client->sendRequest($request);
$responseBody = $response->getBody()->getContents();
$responseData = json_decode($responseBody);
if ($response->getStatusCode() >= 300 && isset($responseData->error)) {
throw new \LogicException(sprintf('Error on %s request %s: %s', $method, $uri, $responseData->error));
} elseif ($response->getStatusCode() >= 300) {
}
if ($response->getStatusCode() >= 300) {
$message = isset($responseData->message) ?? 'Unknown';
throw new \Exception(sprintf('Error on request %s: %s', $response->getStatusCode(), $message));
}
if (null !== $hydrationClass && class_exists($hydrationClass)) {
return $this->denormalizeObject($hydrationClass, $responseData, $isList);
} elseif (null !== $hydrationClass && !class_exists($hydrationClass)) {
}
if (null !== $hydrationClass && !class_exists($hydrationClass)) {
throw new \Exception(sprintf('HydrationClass (%s) does not exist', $hydrationClass));
}
......
......@@ -13,6 +13,8 @@ declare(strict_types=1);
namespace Cwd\PowerDNSClient\Endpoints;
use Cwd\PowerDNSClient\Model\CacheFlushResult;
use Cwd\PowerDNSClient\Model\Config;
use Cwd\PowerDNSClient\Model\Server;
class ServersEndpoint extends AbstractEndpoint
......@@ -55,4 +57,21 @@ class ServersEndpoint extends AbstractEndpoint
// Result is different - denormalize by hand
return $this->getClient()->call(null, sprintf(self::ENDPOINT, $this->defaultServerId).'/statistics', null, false, 'GET');
}
public function cacheFlush(string $domain): CacheFlushResult
{
return $this->getClient()->call(null, sprintf(self::ENDPOINT.'/cache/flush', $this->defaultServerId), CacheFlushResult::class, false, 'PUT', ['domain' => $domain]);
}
/**
* @return Config[]
*
* @throws \Http\Client\Exception
*/
public function config(): array
{
$uri = sprintf(self::ENDPOINT, $this->defaultServerId).'/config';
return $this->getClient()->call(null, $uri, Config::class, true, 'GET');
}
}
......@@ -13,6 +13,7 @@ declare(strict_types=1);
namespace Cwd\PowerDNSClient\Endpoints;
use Cwd\PowerDNSClient\Model\SearchResult;
use Cwd\PowerDNSClient\Model\Zone;
class ZonesEndpoint extends AbstractEndpoint
......@@ -107,7 +108,7 @@ class ZonesEndpoint extends AbstractEndpoint
$payload = $this->getClient()->getSerializer()->serialize($zone, 'json', ['groups' => ['CREATE']]);
return $this->getClient()->call($payload, sprintf(self::ENDPOINT_LIST, $this->defaultServerId), $hydrationClass, false, 'POST', ['rrsets' => $rrsets]);
return $this->getClient()->call($payload, sprintf(self::ENDPOINT_LIST, $this->defaultServerId), $hydrationClass, false, 'POST');
}
/**
......@@ -139,7 +140,7 @@ class ZonesEndpoint extends AbstractEndpoint
{
$queryParams = [];
if (null !== $zoneName) {
$queryParams['zone'] = $zoneName;
$queryParams['zone[]'] = $zoneName;
}
return $this->getClient()->call(null, sprintf(self::ENDPOINT_LIST, $this->defaultServerId), $hydrationClass, true, 'GET', $queryParams);
......@@ -220,4 +221,14 @@ class ZonesEndpoint extends AbstractEndpoint
return $this->getClient()->call(null, sprintf(self::ENDPOINT_ELEMENT, $this->defaultServerId, $zoneId).'/rectify', null, false, 'PUT');
}
public function search($term, $maxResults = 100)
{
$queryParams = [
'q' => $term,
'max' => $maxResults,
];
return $this->getClient()->call(null, sprintf('servers/%s/search-data', $this->defaultServerId), SearchResult::class, true, 'GET', $queryParams);
}
}
<?php
/*
* This file is part of the CwdPowerDNS Client
*
* (c) 2018 cwd.at GmbH <office@cwd.at>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Cwd\PowerDNSClient\Model;
class Config
{
/** @var string|null */
private $type;
/** @var string|null */
private $name;
/** @var string|null */
private $value;
/**
* @return null|string
*/
public function getType(): ?string
{
return $this->type;
}
/**
* @param null|string $type
*
* @return Config
*/
public function setType(?string $type): Config
{
$this->type = $type;
return $this;
}
/**
* @return null|string
*/
public function getName(): ?string
{
return $this->name;
}
/**
* @param null|string $name
*
* @return Config
*/
public function setName(?string $name): Config
{
$this->name = $name;
return $this;
}
/**
* @return null|string
*/
public function getValue(): ?string
{
return $this->value;
}
/**
* @param null|string $value
*
* @return Config
*/
public function setValue(?string $value): Config
{
$this->value = $value;
return $this;
}
}
......@@ -30,5 +30,7 @@ services:
MYSQL_USER: dev
MYSQL_PASS: dev
MYSQL_DB: powerdns
ports:
- 8000:80
......@@ -13,10 +13,56 @@ declare(strict_types=1);
namespace Cwd\PowerDNSClient\Tests;
use Cwd\PowerDNSClient\Model\CacheFlushResult;
use Cwd\PowerDNSClient\Model\Config;
use Cwd\PowerDNSClient\Model\Server;
use Cwd\PowerDNSClient\Model\Zone;
use Webmozart\Assert\Assert;
class ServersEndpointTest extends AbstractTest
{
const ZONE = 'metadata.net.';
public function setup()
{
$zone = (new Zone())
->setName(self::ZONE)
->setKind(Zone::KIND_MASTER)
->addRrset(
(new Zone\RRSet())->setName('www.'.self::ZONE)
->setType('A')
->setTtl(3600)
->addRecord(
(new Zone\Record())->setContent('127.0.0.1')
->setDisabled(false)
)
->addComment(
(new Zone\Comment())->setContent('Test Test')
->setAccount('Max Mustermann')
)
)
->addRrset((new Zone\RRSet())->setName('delete.'.self::ZONE)
->setType('A')
->setTtl(3600)
->addRecord(
(new Zone\Record())->setContent('127.0.0.1')
->setDisabled(false)
)
->addComment((new Zone\Comment())->setContent('test')->setAccount('Maxi'))
)
;
$zone = $this->getClient()->zones()->create($zone, true);
$this->assertNotEmpty($zone->getId());
return $zone;
}
public function tearDown()
{
$this->getClient()->zones()->delete(self::ZONE);
}
public function testStatistics()
{
$stats = $this->getClient()->servers()->statistics();
......@@ -46,4 +92,23 @@ class ServersEndpointTest extends AbstractTest
$this->expectExceptionMessage('Error on request 404:');
$server = $this->getClient()->servers()->get('foobar');
}
public function testCacheFlush()
{
$result = $this->getClient()->servers()->cacheFlush(self::ZONE);
$this->assertInstanceOf(CacheFlushResult::class, $result);
}
public function testCacheFlushNoneCanonical()
{
$this->expectException(\LogicException::class);
$this->getClient()->servers()->cacheFlush('hostname');
}
public function testConfigAll()
{
$result = $this->getClient()->servers()->config();
$this->assertGreaterThan(100, count($result));
Assert::allIsInstanceOf($result, Config::class);
}
}
......@@ -13,6 +13,7 @@ declare(strict_types=1);
namespace Cwd\PowerDNSClient\Tests;
use Cwd\PowerDNSClient\Model\SearchResult;
use Cwd\PowerDNSClient\Model\Zone;
use Cwd\PowerDNSClient\Validator\ValidationException;
use Webmozart\Assert\Assert;
......@@ -411,11 +412,14 @@ class ZonesEndpointTest extends AbstractTest
public function testAllWithNotFoundName()
{
$this->markAsRisky('Does not work as documented');
//$this->getClient()->getClient()->setDebug(true);
$zones = $this->getClient()->zones()->all('asdf.com');
$zones = $this->getClient()->zones()->all('example.com.');
$this->assertTrue(is_array($zones));
//$this->assertEquals(0, count($zones));
Assert::allIsInstanceOf($zones, Zone::class);
//$this->getClient()->getClient()->setDebug(false);
}
/**
......@@ -494,6 +498,44 @@ class ZonesEndpointTest extends AbstractTest
$this->markTestSkipped('not implemented yet');
}
/**
* @depends testCreate
*/
public function testSearch()
{
$result = $this->getClient()->zones()->search('example*');
$this->assertCount(3, $result);
Assert::allIsInstanceOf($result, SearchResult::class);
}
/**
* @depends testCreate
*/
public function testSearchMax()
{
$result = $this->getClient()->zones()->search('example*', 1);
$this->assertCount(2, $result);
Assert::allIsInstanceOf($result, SearchResult::class);
}
/**
* @depends testCreate
*/
public function testSearchSpecific()
{
$result = $this->getClient()->zones()->search('example.com');
$this->assertCount(2, $result);
}
/**
* @depends testCreate
*/
public function testSearchEmpty()
{
$result = $this->getClient()->zones()->search('foobar*', 2);
$this->assertCount(0, $result);
}
/**
* @depends testCreateSlave
*/
......
<?php
/*
* This file is part of the CwdPowerDNS Client
*
* (c) 2018 cwd.at GmbH <office@cwd.at>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Cwd\PowerDNSClient\Tests;
use Cwd\PowerDNSClient\Model\Zone;
use Webmozart\Assert\Assert;
/**
* @group performance
*/
class ZonesPerformanceTest extends AbstractTest
{
private $domainTLD = [
'.com.',
'.net.',
'.at.',
'.de.',
'.hosting.',
'.wien.',
'.cc.',
'.gmbh.',
];
private $createdCount = 0;
private $domains = [];
public function setUp()
{
$domains = [];
for ($i = 0; $i < 100; ++$i) {
$domains[] = $this->generateRandomString(12).$this->domainTLD[rand(0, count($this->domainTLD) - 1)];
}
array_unique($domains);
foreach ($domains as $domain) {
$zone = $this->createZone($domain);
$this->getClient()->zones()->create($zone);
}
$this->createdCount = count($domains);
$this->domains = $domains;
}
public function tearDown()
{
foreach ($this->domains as $domain) {
$this->getClient()->zones()->delete($domain);
}
}
public function testGetAll()
{
$zones = $this->getClient()->zones()->all();
$this->assertCount($this->createdCount, $zones);
Assert::allIsInstanceOf($zones, Zone::class);
}
public function testGetOne()
{
$domain = current($this->domains);
$zone = $this->getClient()->zones()->get($domain);
$this->assertInstanceOf(Zone::class, $zone);
$this->assertCount(3, $zone->getRrsets());
}
private function createZone($domain): Zone
{
$zone = (new Zone())
->setName($domain)
->setKind(Zone::KIND_MASTER)
->addRrset(
(new Zone\RRSet())->setName('www.'.$domain)
->setType('A')
->setTtl(3600)
->addRecord(
(new Zone\Record())->setContent('127.0.0.1')
->setDisabled(false)
)
->addComment(
(new Zone\Comment())->setContent('Test Test')
->setAccount('Max Mustermann')
)
)
->addRrset((new Zone\RRSet())->setName('delete.'.$domain)
->setType('A')
->setTtl(3600)
->addRecord(
(new Zone\Record())->setContent('127.0.0.1')
->setDisabled(false)
)
)
;
return $zone;
}
private function generateRandomString($length = 10)
{
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; ++$i) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment