mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
Restore base behavior
This commit is contained in:
@@ -75,9 +75,7 @@ class GuzzleAdapter implements AdapterInterface, QueryableInterface
|
||||
$options["query"]["time_precision"] = $timePrecision;
|
||||
}
|
||||
|
||||
$endpoint = $this->options->getHttpQueryEndpoint();
|
||||
|
||||
return $this->httpClient->get($endpoint, $options)->json();
|
||||
return $this->get($options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,8 +90,7 @@ class GuzzleAdapter implements AdapterInterface, QueryableInterface
|
||||
],
|
||||
];
|
||||
|
||||
$endpoint = $this->options->getHttpQueryEndpoint();
|
||||
return $this->httpClient->get($endpoint, $options)->json();
|
||||
return $this->get($options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,8 +103,7 @@ class GuzzleAdapter implements AdapterInterface, QueryableInterface
|
||||
"query" => ["q" => "CREATE DATABASE \"{$name}\""],
|
||||
];
|
||||
|
||||
$endpoint = $this->options->getHttpQueryEndpoint();
|
||||
return $this->httpClient->get($endpoint, $httpMessage)->json();
|
||||
return $this->get($httpMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,6 +116,11 @@ class GuzzleAdapter implements AdapterInterface, QueryableInterface
|
||||
"query" => ["q" => "drop database \"{$name}\""],
|
||||
];
|
||||
|
||||
return $this->get($httpMessage);
|
||||
}
|
||||
|
||||
private function get(array $httpMessage)
|
||||
{
|
||||
$endpoint = $this->options->getHttpQueryEndpoint();
|
||||
return $this->httpClient->get($endpoint, $httpMessage)->json();
|
||||
}
|
||||
|
||||
@@ -1,199 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB\Adapter;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\ParseException;
|
||||
use GuzzleHttp\Message\ResponseInterface;
|
||||
use InfluxDB\Exception\InfluxAuthorizationException;
|
||||
use InfluxDB\Exception\InfluxBadResponseException;
|
||||
use InfluxDB\Exception\InfluxGeneralException;
|
||||
use InfluxDB\Exception\InfluxNoSeriesException;
|
||||
use InfluxDB\Exception\InfluxUnexpectedResponseException;
|
||||
use InfluxDB\Options;
|
||||
|
||||
class HttpAdapter implements AdapterInterface, QueryableInterface
|
||||
{
|
||||
const STATUS_CODE_OK = 200;
|
||||
const STATUS_CODE_UNAUTHORIZED = 401;
|
||||
const STATUS_CODE_FORBIDDEN = 403;
|
||||
const STATUS_CODE_BAD_REQUEST = 400;
|
||||
|
||||
/**
|
||||
* @var \InfluxDB\Options
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* @var Client
|
||||
*/
|
||||
private $client;
|
||||
|
||||
/**
|
||||
* @param Options $options
|
||||
*/
|
||||
public function __construct(Options $options, Client $client = null)
|
||||
{
|
||||
$this->options = $options;
|
||||
$this->client = $client ?: new Client();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Options
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $body
|
||||
* @param array $query
|
||||
* @param bool $timePrecision
|
||||
* @return array
|
||||
*/
|
||||
protected function getRequest(array $body = [], array $query = [], $timePrecision = false)
|
||||
{
|
||||
$request = [
|
||||
"auth" => [$this->options->getUsername(), $this->options->getPassword()],
|
||||
"exceptions" => false
|
||||
];
|
||||
if (count($body)) {
|
||||
$request['body'] = json_encode($body);
|
||||
}
|
||||
if (count($query)) {
|
||||
$request['query'] = $query;
|
||||
}
|
||||
if ($timePrecision) {
|
||||
$request["query"]["time_precision"] = $timePrecision;
|
||||
}
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ResponseInterface $response
|
||||
* @return mixed
|
||||
* @throws \InfluxDB\Exception\InfluxGeneralException
|
||||
* @throws \InfluxDB\Exception\InfluxAuthorizationException
|
||||
* @throws \InfluxDB\Exception\InfluxNoSeriesException
|
||||
*/
|
||||
protected function parseResponse(ResponseInterface $response)
|
||||
{
|
||||
$statusCode = $response->getStatusCode();
|
||||
if ($statusCode >= 400 && $statusCode < 500) {
|
||||
$message = (string)$response->getBody();
|
||||
if (!$message) {
|
||||
$message = $response->getReasonPhrase();
|
||||
}
|
||||
switch ($statusCode) {
|
||||
case self::STATUS_CODE_UNAUTHORIZED:
|
||||
case self::STATUS_CODE_FORBIDDEN:
|
||||
throw new InfluxAuthorizationException($message, $statusCode);
|
||||
case self::STATUS_CODE_BAD_REQUEST:
|
||||
if (strpos($message, "Couldn't find series:") !== false) {
|
||||
throw new InfluxNoSeriesException($message, $statusCode);
|
||||
}
|
||||
}
|
||||
throw new InfluxGeneralException($message, $statusCode);
|
||||
} else if ($statusCode == self::STATUS_CODE_OK) {
|
||||
try {
|
||||
return $response->json();
|
||||
} catch (ParseException $ex) {
|
||||
throw new InfluxBadResponseException(
|
||||
sprintf("%s; Response is '%s'", $ex->getMessage(), (string)$response->getBody()),
|
||||
$ex->getCode(), $ex
|
||||
);
|
||||
}
|
||||
} else if ($statusCode > 200 && $statusCode < 300) {
|
||||
return true;
|
||||
}
|
||||
throw new InfluxUnexpectedResponseException((string)$response->getBody(), $statusCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $message
|
||||
* @param bool $timePrecision
|
||||
* @return \GuzzleHttp\Message\ResponseInterface
|
||||
*/
|
||||
public function send($message, $timePrecision = false)
|
||||
{
|
||||
try {
|
||||
$response = $this->client->post(
|
||||
$this->options->getHttpSeriesEndpoint(),
|
||||
$this->getRequest($message, [], $timePrecision)
|
||||
);
|
||||
} catch (\Exception $ex) {
|
||||
throw new InfluxGeneralException($ex->getMessage(), $ex->getCode(), $ex);
|
||||
}
|
||||
return $this->parseResponse($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $query
|
||||
* @param bool $timePrecision
|
||||
* @return mixed
|
||||
*/
|
||||
public function query($query, $timePrecision = false)
|
||||
{
|
||||
try {
|
||||
$response = $this->client->get(
|
||||
$this->options->getHttpSeriesEndpoint(),
|
||||
$this->getRequest([], ["q" => $query], $timePrecision)
|
||||
);
|
||||
} catch (\Exception $ex) {
|
||||
throw new InfluxGeneralException($ex->getMessage(), $ex->getCode(), $ex);
|
||||
}
|
||||
return $this->parseResponse($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDatabases()
|
||||
{
|
||||
try {
|
||||
$response = $this->client->get(
|
||||
$this->options->getHttpDatabaseEndpoint(),
|
||||
$this->getRequest()
|
||||
);
|
||||
} catch (\Exception $ex) {
|
||||
throw new InfluxGeneralException($ex->getMessage(), $ex->getCode(), $ex);
|
||||
}
|
||||
return $this->parseResponse($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function createDatabase($name)
|
||||
{
|
||||
try {
|
||||
$response = $this->client->post(
|
||||
$this->options->getHttpDatabaseEndpoint(),
|
||||
$this->getRequest(["name" => $name])
|
||||
);
|
||||
} catch (\Exception $ex) {
|
||||
throw new InfluxGeneralException($ex->getMessage(), $ex->getCode(), $ex);
|
||||
}
|
||||
return $this->parseResponse($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function deleteDatabase($name)
|
||||
{
|
||||
try {
|
||||
$response = $this->client->delete(
|
||||
$this->options->getHttpDatabaseEndpoint($name),
|
||||
$this->getRequest()
|
||||
);
|
||||
} catch (\Exception $ex) {
|
||||
throw new InfluxGeneralException($ex->getMessage(), $ex->getCode(), $ex);
|
||||
}
|
||||
return $this->parseResponse($response);
|
||||
}
|
||||
}
|
||||
|
||||
+8
-47
@@ -10,57 +10,35 @@ use InfluxDB\Filter\FilterInterface;
|
||||
*/
|
||||
class Client
|
||||
{
|
||||
/**
|
||||
* @var \InfluxDB\Adapter\AdapterInterface
|
||||
*/
|
||||
private $adapter;
|
||||
|
||||
/**
|
||||
* Set InfluxDB adapter
|
||||
* @param Adapter\AdapterInterface
|
||||
* @return Client
|
||||
*/
|
||||
public function setAdapter(Adapter\AdapterInterface $adapter)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get adapter
|
||||
* @return Adapter\AdapterInterface
|
||||
*/
|
||||
public function getAdapter()
|
||||
{
|
||||
return $this->adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert point into series
|
||||
* @param string $name
|
||||
* @param array $value
|
||||
* @param bool|string $timePrecision
|
||||
* @return mixed
|
||||
*/
|
||||
public function mark($name, array $values = [], $timePrecision = false)
|
||||
{
|
||||
$data =[];
|
||||
$data = $name;
|
||||
if (!is_array($name)) {
|
||||
$data =[];
|
||||
|
||||
$timePrecision = $this->clearTimePrecision($timePrecision);
|
||||
$timePrecision = $this->clearTimePrecision($timePrecision);
|
||||
|
||||
$data["database"] = $this->getAdapter()->getOptions()->getDatabase();
|
||||
$data['points'][0]['name'] = $name;
|
||||
$data['points'][0]['fields'] = $values;
|
||||
$data["database"] = $this->getAdapter()->getOptions()->getDatabase();
|
||||
$data['points'][0]['name'] = $name;
|
||||
$data['points'][0]['fields'] = $values;
|
||||
}
|
||||
|
||||
return $this->getAdapter()->send($data, $timePrecision);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a query into database
|
||||
* @param string $query
|
||||
* @param bool|string $timePrecision
|
||||
* @return array
|
||||
*/
|
||||
public function query($query, $timePrecision = false)
|
||||
{
|
||||
if (!($this->getAdapter() instanceOf QueryableInterface)) {
|
||||
@@ -74,10 +52,6 @@ class Client
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of databases
|
||||
* @return array
|
||||
*/
|
||||
public function getDatabases()
|
||||
{
|
||||
if (!($this->getAdapter() instanceOf QueryableInterface)) {
|
||||
@@ -86,10 +60,6 @@ class Client
|
||||
return $this->getAdapter()->getDatabases();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create database by name
|
||||
* @param string $name
|
||||
*/
|
||||
public function createDatabase($name)
|
||||
{
|
||||
if (!($this->getAdapter() instanceOf QueryableInterface)) {
|
||||
@@ -98,10 +68,6 @@ class Client
|
||||
return $this->getAdapter()->createDatabase($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete database by name
|
||||
* @param string $name
|
||||
*/
|
||||
public function deleteDatabase($name)
|
||||
{
|
||||
if (!($this->getAdapter() instanceOf QueryableInterface)) {
|
||||
@@ -110,11 +76,6 @@ class Client
|
||||
return $this->getAdapter()->deleteDatabase($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* List of time precision choose
|
||||
* @param string $timePrecision
|
||||
* @return bool|string
|
||||
*/
|
||||
private function clearTimePrecision($timePrecision)
|
||||
{
|
||||
switch ($timePrecision) {
|
||||
|
||||
@@ -44,9 +44,6 @@ abstract class ClientFactory
|
||||
case 'InfluxDB\\Adapter\\GuzzleAdapter':
|
||||
$adapter = new $adapterName(new GuzzleClient($options["adapter"]["options"]), $adapterOptions);
|
||||
break;
|
||||
case 'InfluxDB\\Adapter\\HttpAdapter':
|
||||
$adapter = new $adapterName($adapterOptions, new GuzzleClient($options["adapter"]["options"]));
|
||||
break;
|
||||
default:
|
||||
throw new \InvalidArgumentException("Missing adapter {$adapter}");
|
||||
}
|
||||
|
||||
@@ -79,7 +79,6 @@ class ClientFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
return [
|
||||
["InfluxDB\\Adapter\\GuzzleAdapter"],
|
||||
["InfluxDB\\Adapter\\HttpAdapter"],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -70,11 +70,13 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$this->object->mark("tcp.test", ["mark" => "element"]);
|
||||
|
||||
$body = $this->object->query("select * from tcp.test");
|
||||
sleep(1);
|
||||
|
||||
$this->assertCount(1, $body);
|
||||
$this->assertEquals("tcp.test", $body[0]["name"]);
|
||||
$this->assertEquals("element", $body[0]["points"][0][2]);
|
||||
$body = $this->object->query("select * from \"tcp.test\"");
|
||||
|
||||
$this->assertCount(1, $body["results"][0]["series"][0]["values"]);
|
||||
$this->assertEquals("mark", $body["results"][0]["series"][0]["columns"][1]);
|
||||
$this->assertEquals("element", $body["results"][0]["series"][0]["values"][0][1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,10 +88,13 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
$this->object->mark("tcp.test", ["mark" => "element2"]);
|
||||
$this->object->mark("tcp.test", ["mark" => "element3"]);
|
||||
|
||||
$body = $this->object->query("select mark from tcp.test", "s");
|
||||
sleep(1);
|
||||
|
||||
$this->assertCount(3, $body[0]["points"]);
|
||||
$this->assertEquals("tcp.test", $body[0]["name"]);
|
||||
$body = $this->object->query("select mark from \"tcp.test\"", "s");
|
||||
|
||||
$this->assertCount(3, $body["results"][0]["series"][0]["values"]);
|
||||
$this->assertEquals("mark", $body["results"][0]["series"][0]["columns"][1]);
|
||||
$this->assertEquals("element", $body["results"][0]["series"][0]["values"][0][1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,12 +102,16 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testGuzzleHttpQueryApiWithTimePrecision()
|
||||
{
|
||||
$this->markTestSkipped("Skip time precision");
|
||||
$this->object->mark("tcp.test", ["mark" => "element"]);
|
||||
|
||||
$body = $this->object->query("select mark from tcp.test", "s");
|
||||
sleep(1);
|
||||
|
||||
$this->assertCount(1, $body[0]["points"]);
|
||||
$this->assertEquals("tcp.test", $body[0]["name"]);
|
||||
$body = $this->object->query("select mark from \"tcp.test\"", "s");
|
||||
|
||||
$this->assertCount(1, $body["results"][0]["series"][0]["values"]);
|
||||
$this->assertEquals("mark", $body["results"][0]["series"][0]["columns"][1]);
|
||||
$this->assertEquals("element", $body["results"][0]["series"][0]["values"][0][1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,9 +119,12 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testGuzzleHttpWriteApiWithTimePrecision()
|
||||
{
|
||||
$this->markTestSkipped("Skip time precision");
|
||||
$this->object->mark("tcp.test", ["time" => 1410591552, "mark" => "element"], "s");
|
||||
|
||||
$body = $this->object->query("select mark from tcp.test", "ms");
|
||||
sleep(1);
|
||||
|
||||
$body = $this->object->query("select mark from \"tcp.test\"", "ms");
|
||||
|
||||
$this->assertCount(1, $body[0]["points"]);
|
||||
$this->assertEquals("tcp.test", $body[0]["name"]);
|
||||
@@ -131,6 +143,7 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
$options->setUsername($rawOptions["udp"]["username"]);
|
||||
$options->setPassword($rawOptions["udp"]["password"]);
|
||||
$options->setPort($rawOptions["udp"]["port"]);
|
||||
$options->setDatabase($rawOptions["udp"]["database"]);
|
||||
|
||||
$adapter = new UdpAdapter($options);
|
||||
$object = new Client();
|
||||
@@ -142,28 +155,32 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
$object->mark("udp.test", ["mark" => "element3"]);
|
||||
|
||||
// Wait UDP/IP message arrives
|
||||
usleep(200e3);
|
||||
sleep(1);
|
||||
|
||||
$this->options->setDatabase("udp.test");
|
||||
$body = $this->object->query("select * from udp.test");
|
||||
$body = $this->object->query("select * from \"udp.test\"");
|
||||
|
||||
$this->assertCount(4, $body[0]["points"]);
|
||||
$this->assertEquals("udp.test", $body[0]["name"]);
|
||||
$this->assertCount(4, $body["results"][0]["series"][0]["values"]);
|
||||
$this->assertEquals("mark", $body["results"][0]["series"][0]["columns"][1]);
|
||||
$this->assertEquals("element", $body["results"][0]["series"][0]["values"][0][1]);
|
||||
}
|
||||
|
||||
public function testListActiveDatabses()
|
||||
{
|
||||
$databases = $this->object->getDatabases();
|
||||
|
||||
$this->assertCount(2, $databases);
|
||||
$this->assertCount(2, $databases["results"][0]["series"][0]["values"]);
|
||||
}
|
||||
|
||||
public function testCreateANewDatabase()
|
||||
{
|
||||
$this->object->createDatabase("walter");
|
||||
|
||||
sleep(1);
|
||||
|
||||
$databases = $this->object->getDatabases();
|
||||
|
||||
$this->assertCount(3, $databases);
|
||||
$this->assertCount(3, $databases["results"][0]["series"][0]["values"]);
|
||||
|
||||
$this->object->deleteDatabase("walter");
|
||||
}
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
<?php
|
||||
namespace InfluxDB;
|
||||
|
||||
use InfluxDB\Adapter\HttpAdapter;
|
||||
use InfluxDB\Adapter\UdpAdapter;
|
||||
use InfluxDB\Filter\ColumnsPointsFilter;
|
||||
|
||||
class HttpAdapterTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
private $rawOptions;
|
||||
private $object;
|
||||
private $options;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->markTestSkipped();
|
||||
|
||||
$options = include __DIR__ . '/../bootstrap.php';
|
||||
$this->rawOptions = $options;
|
||||
|
||||
$tcpOptions = $options["tcp"];
|
||||
|
||||
$options = new Options();
|
||||
$options->setHost($tcpOptions["host"]);
|
||||
$options->setPort($tcpOptions["port"]);
|
||||
$options->setUsername($tcpOptions["username"]);
|
||||
$options->setPassword($tcpOptions["password"]);
|
||||
$options->setDatabase($tcpOptions["database"]);
|
||||
|
||||
$this->options = $options;
|
||||
|
||||
$adapter = new HttpAdapter($options);
|
||||
|
||||
$influx = new Client();
|
||||
$influx->setAdapter($adapter);
|
||||
$this->object = $influx;
|
||||
|
||||
$databases = $this->object->getDatabases();
|
||||
foreach ($databases as $database) {
|
||||
$this->object->deleteDatabase($database["name"]);
|
||||
}
|
||||
|
||||
$this->object->createDatabase($this->rawOptions["tcp"]["database"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group tcp
|
||||
*/
|
||||
public function testApiWorksCorrectly()
|
||||
{
|
||||
$this->object->mark("tcp.test", ["mark" => "element"]);
|
||||
|
||||
$body = $this->object->query("select * from tcp.test");
|
||||
$this->assertCount(1, $body[0]["points"]);
|
||||
$this->assertEquals("element", $body[0]["points"][0][2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group tcp
|
||||
*/
|
||||
public function testQueryApiWorksCorrectly()
|
||||
{
|
||||
$this->object->mark("tcp.test", ["mark" => "element"]);
|
||||
|
||||
$body = $this->object->query("select * from tcp.test");
|
||||
|
||||
$this->assertCount(1, $body);
|
||||
$this->assertEquals("tcp.test", $body[0]["name"]);
|
||||
$this->assertEquals("element", $body[0]["points"][0][2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group tcp
|
||||
*/
|
||||
public function testQueryApiWithMultipleData()
|
||||
{
|
||||
$this->object->mark("tcp.test", ["mark" => "element"]);
|
||||
$this->object->mark("tcp.test", ["mark" => "element2"]);
|
||||
$this->object->mark("tcp.test", ["mark" => "element3"]);
|
||||
|
||||
$body = $this->object->query("select mark from tcp.test", "s");
|
||||
|
||||
$this->assertCount(3, $body[0]["points"]);
|
||||
$this->assertEquals("tcp.test", $body[0]["name"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group tcp
|
||||
*/
|
||||
public function testQueryApiWithTimePrecision()
|
||||
{
|
||||
$this->object->mark("tcp.test", ["mark" => "element"]);
|
||||
|
||||
$body = $this->object->query("select mark from tcp.test", "s");
|
||||
|
||||
$this->assertCount(1, $body[0]["points"]);
|
||||
$this->assertEquals("tcp.test", $body[0]["name"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group tcp
|
||||
*/
|
||||
public function testWriteApiWithTimePrecision()
|
||||
{
|
||||
$this->object->mark("tcp.test", ["time" => 1410591552, "mark" => "element"], "s");
|
||||
|
||||
$body = $this->object->query("select mark from tcp.test", "ms");
|
||||
|
||||
$this->assertCount(1, $body[0]["points"]);
|
||||
$this->assertEquals("tcp.test", $body[0]["name"]);
|
||||
|
||||
$this->assertEquals("1410591552000", $body[0]["points"][0][0]);
|
||||
}
|
||||
|
||||
public function testListActiveDatabses()
|
||||
{
|
||||
$databases = $this->object->getDatabases();
|
||||
|
||||
$this->assertCount(1, $databases);
|
||||
}
|
||||
|
||||
public function testCreateANewDatabase()
|
||||
{
|
||||
$this->object->createDatabase("walter");
|
||||
$databases = $this->object->getDatabases();
|
||||
|
||||
$this->assertCount(2, $databases);
|
||||
|
||||
$this->object->deleteDatabase("walter");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user