version 1.5
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB2Test;
|
||||
|
||||
use GuzzleHttp\Handler\MockHandler;
|
||||
use GuzzleHttp\HandlerStack;
|
||||
use GuzzleHttp\Middleware;
|
||||
use InfluxDB2\Client;
|
||||
use InfluxDB2\Model\WritePrecision;
|
||||
use InfluxDB2\QueryApi;
|
||||
use InfluxDB2\WriteApi;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Parent class for all units tests that uses mocked InfluxDB server
|
||||
* @package InfluxDB2Test
|
||||
*/
|
||||
abstract class BasicTest extends TestCase
|
||||
{
|
||||
/** @var Client */
|
||||
protected $client;
|
||||
/** @var WriteApi */
|
||||
protected $writeApi;
|
||||
/** @var QueryApi */
|
||||
protected $queryApi;
|
||||
/** @var MockHandler */
|
||||
protected $mockHandler;
|
||||
/** @var array */
|
||||
protected $requests;
|
||||
|
||||
/**
|
||||
* @before
|
||||
* @param string $url
|
||||
* @param string $logFile default log file
|
||||
*/
|
||||
public function setUp($url = "http://localhost:8086", $logFile = "php://output"): void
|
||||
{
|
||||
$this->client = new Client([
|
||||
"url" => $url,
|
||||
"token" => "my-token",
|
||||
"bucket" => "my-bucket",
|
||||
"precision" => WritePrecision::NS,
|
||||
"org" => "my-org",
|
||||
"logFile" => $logFile
|
||||
]);
|
||||
|
||||
$this->writeApi = $this->client->createWriteApi($this->getWriteOptions());
|
||||
$this->queryApi = $this->client->createQueryApi();
|
||||
|
||||
$this->mockHandler = new MockHandler();
|
||||
|
||||
$this->requests = [];
|
||||
|
||||
$handlerStack = HandlerStack::create($this->mockHandler);
|
||||
$handlerStack->push(Middleware::history($this->requests));
|
||||
|
||||
$this->writeApi->http = $this->writeApi->configuredClient(new \GuzzleHttp\Client([
|
||||
'handler' => $handlerStack,
|
||||
]));
|
||||
|
||||
$this->queryApi->http = $this->writeApi->configuredClient(new \GuzzleHttp\Client([
|
||||
'handler' => $handlerStack,
|
||||
]));
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
$this->client->close();
|
||||
}
|
||||
|
||||
protected function getWriteOptions(): ?array
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB2Test;
|
||||
|
||||
use Exception;
|
||||
use InfluxDB2\Client;
|
||||
use IntegrationBaseTestCase;
|
||||
|
||||
require_once('IntegrationBaseTestCase.php');
|
||||
|
||||
/**
|
||||
* @group integration
|
||||
*/
|
||||
class ClientTest extends IntegrationBaseTestCase
|
||||
{
|
||||
public function test_health()
|
||||
{
|
||||
$health = $this->client->health();
|
||||
|
||||
$this->assertEquals('ready for queries and writes', $health->getMessage());
|
||||
$this->assertEquals('influxdb', $health->getName());
|
||||
$this->assertEquals('pass', $health->getStatus());
|
||||
}
|
||||
|
||||
public function test_health_not_running()
|
||||
{
|
||||
$this->client->close();
|
||||
$this->client = new Client([
|
||||
"url" => "http://localhost:8099",
|
||||
"token" => "my-token",
|
||||
]);
|
||||
|
||||
$health = $this->client->health();
|
||||
|
||||
$this->assertStringContainsString('Failed to connect to localhost port 8099', $health->getMessage());
|
||||
$this->assertEquals('influxdb', $health->getName());
|
||||
$this->assertEquals('fail', $health->getStatus());
|
||||
}
|
||||
|
||||
public function test_ping()
|
||||
{
|
||||
$ping = $this->client->ping();
|
||||
|
||||
$this->assertArrayHasKey('X-Influxdb-Build', $ping);
|
||||
$this->assertArrayHasKey('X-Influxdb-Version', $ping);
|
||||
}
|
||||
|
||||
public function test_ping_not_running()
|
||||
{
|
||||
$this->client->close();
|
||||
$this->client = new Client([
|
||||
"url" => "http://localhost:8099",
|
||||
"token" => "my-token",
|
||||
]);
|
||||
|
||||
$this->expectException(Exception::class);
|
||||
$this->expectExceptionMessage("Failed to connect to localhost");
|
||||
|
||||
$this->client->ping();
|
||||
}
|
||||
|
||||
public function test_debug()
|
||||
{
|
||||
$logFilePath = stream_get_meta_data(tmpfile())['uri'];
|
||||
$this->client->close();
|
||||
$this->client = new Client([
|
||||
"url" => "http://localhost:8086",
|
||||
"token" => "my-token",
|
||||
"debug" => true,
|
||||
"logFile" => $logFilePath
|
||||
]);
|
||||
|
||||
$tables = $this->client->createQueryApi()->query("buckets()", "my-org");
|
||||
$this->assertCount(1, $tables);
|
||||
|
||||
$this->assertStringContainsString('Authorization: ***', file_get_contents($logFilePath));
|
||||
unlink($logFilePath);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB2Test;
|
||||
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use InfluxDB2\ApiException;
|
||||
use InfluxDB2\Client;
|
||||
use InfluxDB2\Model\WritePrecision;
|
||||
use InvalidArgumentException;
|
||||
use ReflectionObject;
|
||||
|
||||
require_once('BasicTest.php');
|
||||
|
||||
class DefaultApiTest extends BasicTest
|
||||
{
|
||||
public function testUserAgent()
|
||||
{
|
||||
$this->mockHandler->append(new Response(204));
|
||||
$this->writeApi->write('h2o,location=west value=33i 15');
|
||||
|
||||
$request = $this->mockHandler->getLastRequest();
|
||||
|
||||
$this->assertStringStartsWith(
|
||||
'influxdb-client-php/',
|
||||
strval($request->getHeader("User-Agent")[0])
|
||||
);
|
||||
}
|
||||
|
||||
public function testTrailingSlashInUrl()
|
||||
{
|
||||
$this->mockHandler->append(new Response(204));
|
||||
$this->writeApi->write('h2o,location=west value=33i 15');
|
||||
|
||||
$request = $this->mockHandler->getLastRequest();
|
||||
|
||||
$this->assertEquals('http://localhost:8086/api/v2/write?org=my-org&bucket=my-bucket&precision=ns', strval($request->getUri()));
|
||||
|
||||
$this->tearDown();
|
||||
$this->setUp("http://localhost:8086/");
|
||||
|
||||
$this->mockHandler->append(new Response(204));
|
||||
$this->writeApi->write('h2o,location=west value=33i 15');
|
||||
|
||||
$request = $this->mockHandler->getLastRequest();
|
||||
|
||||
$this->assertEquals('http://localhost:8086/api/v2/write?org=my-org&bucket=my-bucket&precision=ns', strval($request->getUri()));
|
||||
}
|
||||
|
||||
public function testContentType()
|
||||
{
|
||||
$this->mockHandler->append(new Response(204));
|
||||
$this->writeApi->write('h2o,location=west value=33i 15');
|
||||
|
||||
$request = $this->mockHandler->getLastRequest();
|
||||
|
||||
$this->assertNotEmpty($request->getHeader("Content-Type"));
|
||||
}
|
||||
|
||||
public function testApiException()
|
||||
{
|
||||
$this->mockHandler->append(new Response(400));
|
||||
|
||||
$this->expectException(ApiException::class);
|
||||
|
||||
$this->writeApi->write('h2o,location=west value=33i 15');
|
||||
}
|
||||
|
||||
public function testInvalidArgument()
|
||||
{
|
||||
$this->mockHandler->append(new Response(204));
|
||||
|
||||
$this->writeApi->options["org"] = '';
|
||||
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
$this->writeApi->write('h2o,location=west value=33i 15');
|
||||
}
|
||||
|
||||
public function testDefaultVerifySSL()
|
||||
{
|
||||
$guzzle = $this->property_value($this->property_value($this->writeApi->http, 'client'), 'httpClient');
|
||||
|
||||
$this->assertEquals(true, $guzzle->getConfig()['verify']);
|
||||
}
|
||||
|
||||
public function testConfigureVerifySSL()
|
||||
{
|
||||
$client = new Client([
|
||||
"url" => "http://localhost:8086",
|
||||
"token" => "my-token",
|
||||
"bucket" => "my-bucket",
|
||||
"precision" => WritePrecision::NS,
|
||||
"org" => "my-org",
|
||||
"logFile" => "php://output",
|
||||
"verifySSL" => false
|
||||
]);
|
||||
|
||||
$guzzle = $this->property_value($this->property_value($client->createQueryApi()->http, 'client'), 'httpClient');
|
||||
|
||||
$this->assertEquals(false, $guzzle->getConfig()['verify']);
|
||||
|
||||
$client->close();
|
||||
}
|
||||
|
||||
public function testFollowRedirect()
|
||||
{
|
||||
$this->mockHandler->append(
|
||||
new Response(
|
||||
307,
|
||||
['location' => 'http://localhost:8086']
|
||||
),
|
||||
new Response(204, [], "{\"status\": \"pass\"}")
|
||||
);
|
||||
$this->writeApi->write('h2o,location=west value=33i 15');
|
||||
|
||||
$this->assertCount(2, $this->requests);
|
||||
|
||||
$this->assertEquals('Token my-token', $this->getHeader($this->requests[0]['request']));
|
||||
$this->assertEquals('Token my-token', $this->getHeader($this->requests[1]['request']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request with headers
|
||||
* @return string Authorization headers
|
||||
*/
|
||||
private function getHeader(Request $request): string
|
||||
{
|
||||
return implode(' ', $request->getHeaders()['Authorization']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \ReflectionException fail to access property
|
||||
*/
|
||||
private function property_value(object $object, string $property_name): object
|
||||
{
|
||||
$reflection = new ReflectionObject($object);
|
||||
$property = $reflection->getProperty($property_name);
|
||||
$property->setAccessible(true);
|
||||
return $property->getValue($object);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB2Test;
|
||||
|
||||
use Exception;
|
||||
use InfluxDB2\FluxCsvParser;
|
||||
use InfluxDB2\FluxCsvParserException;
|
||||
use InfluxDB2\FluxQueryError;
|
||||
use InfluxDB2\FluxRecord;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FluxCsvParserTest extends TestCase
|
||||
{
|
||||
public function testMultipleValues()
|
||||
{
|
||||
$data = "#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,string,string,string,string,long,long,string\n" .
|
||||
"#group,false,false,true,true,true,true,true,true,false,false,false\n" .
|
||||
"#default,_result,,,,,,,,,,\n" .
|
||||
",result,table,_start,_stop,_field,_measurement,host,region,_value2,value1,value_str\n" .
|
||||
",,0,1677-09-21T00:12:43.145224192Z,2018-07-16T11:21:02.547596934Z,free,mem,A,west,121,11,test\n" .
|
||||
",,1,1677-09-21T00:12:43.145224192Z,2018-07-16T11:21:02.547596934Z,free,mem,B,west,484,22,test\n" .
|
||||
",,2,1677-09-21T00:12:43.145224192Z,2018-07-16T11:21:02.547596934Z,usage_system,cpu,A,west,1444,38,test\n" .
|
||||
',,3,1677-09-21T00:12:43.145224192Z,2018-07-16T11:21:02.547596934Z,user_usage,cpu,A,west,2401,49,test';
|
||||
|
||||
$fluxCsvParser = new FluxCsvParser($data);
|
||||
$tables = $fluxCsvParser->parse()->tables;
|
||||
$columnHeaders = $tables[0]->columns;
|
||||
|
||||
$this->assertEquals(11, sizeof($columnHeaders));
|
||||
$values = [false, false, true, true, true, true, true, true, false, false, false];
|
||||
$this->assertColumns($columnHeaders, $values);
|
||||
$this->assertEquals(4, sizeof($tables));
|
||||
|
||||
$this->assertMultipleRecords($tables);
|
||||
}
|
||||
|
||||
public function testParseShortCut()
|
||||
{
|
||||
$data = '#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,' .
|
||||
"dateTime:RFC3339,long,string,string,string,boolean\n" .
|
||||
"#group,false,false,false,false,false,false,false,false,false,true\n" .
|
||||
"#default,_result,,,,,,,,,true\n" .
|
||||
",result,table,_start,_stop,_time,_value,_field,_measurement,host,value\n" .
|
||||
",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,true\n";
|
||||
|
||||
$fluxCsvParser = new FluxCsvParser($data);
|
||||
$tables = $fluxCsvParser->parse()->tables;
|
||||
|
||||
$this->assertEquals(1, sizeof($tables));
|
||||
$this->assertEquals(1, sizeof($tables[0]->records));
|
||||
|
||||
$record = $tables[0]->records[0];
|
||||
$this->assertEquals($this->parseTime('1970-01-01T00:00:10Z'), $record->getStart());
|
||||
$this->assertEquals($this->parseTime('1970-01-01T00:00:20Z'), $record->getStop());
|
||||
$this->assertEquals($this->parseTime('1970-01-01T00:00:10Z'), $record->getTime());
|
||||
|
||||
$this->assertEquals(10, sizeof($record->values));
|
||||
$this->assertEquals("free", $record->getField());
|
||||
$this->assertEquals("mem", $record->getMeasurement());
|
||||
}
|
||||
|
||||
public function testMappingBoolean()
|
||||
{
|
||||
$data = '#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,' .
|
||||
"dateTime:RFC3339,long,string,string,string,boolean\n" .
|
||||
"#group,false,false,false,false,false,false,false,false,false,true\n" .
|
||||
"#default,_result,,,,,,,,,true\n" .
|
||||
",result,table,_start,_stop,_time,_value,_field,_measurement,host,value\n" .
|
||||
",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,true\n" .
|
||||
",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,false\n" .
|
||||
",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,x\n" .
|
||||
",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,\n";
|
||||
|
||||
$fluxCsvParser = new FluxCsvParser($data);
|
||||
$tables = $fluxCsvParser->parse()->tables;
|
||||
|
||||
$this->assertEquals(1, sizeof($tables));
|
||||
$this->assertEquals(4, sizeof($tables[0]->records));
|
||||
|
||||
$records = $tables[0]->records;
|
||||
|
||||
$this->assertEquals(true, $records[0]->values['value']);
|
||||
$this->assertEquals(false, $records[1]->values['value']);
|
||||
$this->assertEquals(false, $records[2]->values['value']);
|
||||
$this->assertEquals(true, $records[3]->values['value']);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO - PHP supports only signed 64bit integers
|
||||
*/
|
||||
public function testMappingUnsignedLong()
|
||||
{
|
||||
$data = '#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,' .
|
||||
"dateTime:RFC3339,long,string,string,string,unsignedLong\n" .
|
||||
"#group,false,false,false,false,false,false,false,false,false,true\n" .
|
||||
"#default,_result,,,,,,,,,\n" .
|
||||
",result,table,_start,_stop,_time,_value,_field,_measurement,host,value\n" .
|
||||
",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,17916881237904312345\n" .
|
||||
",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,\n";
|
||||
|
||||
//TODO this does not work due "overflow"
|
||||
$expected = intval("17916881237904312345");
|
||||
|
||||
$fluxCsvParser = new FluxCsvParser($data);
|
||||
$tables = $fluxCsvParser->parse()->tables;
|
||||
|
||||
$records = $tables[0]->records;
|
||||
$this->assertEquals($expected, $records[0]->values['value']);
|
||||
$this->assertNull($records[1]->values['value']);
|
||||
}
|
||||
|
||||
public function testMappingDouble()
|
||||
{
|
||||
$data = '#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,' .
|
||||
"dateTime:RFC3339,long,string,string,string,double\n" .
|
||||
"#group,false,false,false,false,false,false,false,false,false,true\n" .
|
||||
"#default,_result,,,,,,,,,\n" .
|
||||
",result,table,_start,_stop,_time,_value,_field,_measurement,host,value\n" .
|
||||
",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,12.25\n" .
|
||||
",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,\n";
|
||||
|
||||
$fluxCsvParser = new FluxCsvParser($data);
|
||||
$tables = $fluxCsvParser->parse()->tables;
|
||||
|
||||
$records = $tables[0]->records;
|
||||
|
||||
$this->assertEquals(12.25, $records[0]->values['value']);
|
||||
$this->assertNull($records[1]->values['value']);
|
||||
}
|
||||
|
||||
public function testMappingBase64Binary()
|
||||
{
|
||||
$binaryData = 'test value';
|
||||
$encodedData = base64_encode($binaryData);
|
||||
|
||||
$data = '#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,' .
|
||||
"dateTime:RFC3339,long,string,string,string,base64Binary\n" .
|
||||
"#group,false,false,false,false,false,false,false,false,false,true\n" .
|
||||
"#default,_result,,,,,,,,,\n" .
|
||||
",result,table,_start,_stop,_time,_value,_field,_measurement,host,value\n" .
|
||||
',,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,' . $encodedData . "\n" .
|
||||
",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,\n";
|
||||
|
||||
$fluxCsvParser = new FluxCsvParser($data);
|
||||
$tables = $fluxCsvParser->parse()->tables;
|
||||
|
||||
$records = $tables[0]->records;
|
||||
|
||||
$this->assertEquals($binaryData, $records[0]->values['value']);
|
||||
$this->assertNull($records[1]->values['value']);
|
||||
}
|
||||
|
||||
public function testMappingDuration()
|
||||
{
|
||||
$data = '#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339' .
|
||||
",dateTime:RFC3339,long,string,string,string,duration\n" .
|
||||
"#group,false,false,false,false,false,false,false,false,false,true\n" .
|
||||
"#default,_result,,,,,,,,,\n" .
|
||||
",result,table,_start,_stop,_time,_value,_field,_measurement,host,value\n" .
|
||||
",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,125\n" .
|
||||
",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,\n";
|
||||
|
||||
$fluxCsvParser = new FluxCsvParser($data);
|
||||
$tables = $fluxCsvParser->parse()->tables;
|
||||
|
||||
$records = $tables[0]->records;
|
||||
|
||||
$this->assertEquals(125, $records[0]->values['value']);
|
||||
$this->assertNull($records[1]->values['value']);
|
||||
}
|
||||
|
||||
public function testGroupKey()
|
||||
{
|
||||
$data = '#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,' .
|
||||
"dateTime:RFC3339,long,string,string,string,duration\n" .
|
||||
"#group,false,false,false,false,true,false,false,false,false,true\n" .
|
||||
"#default,_result,,,,,,,,,\n" .
|
||||
",result,table,_start,_stop,_time,_value,_field,_measurement,host,value\n" .
|
||||
",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,125\n" .
|
||||
",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,\n";
|
||||
|
||||
$fluxCsvParser = new FluxCsvParser($data);
|
||||
$tables = $fluxCsvParser->parse()->tables;
|
||||
|
||||
$this->assertEquals(10, count($tables[0]->columns));
|
||||
$this->assertEquals(2, count($tables[0]->getGroupKey()));
|
||||
}
|
||||
|
||||
public function testUnknownTypeAsString()
|
||||
{
|
||||
$data = '#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,' .
|
||||
"dateTime:RFC3339,long,string,string,string,unknown\n" .
|
||||
"#group,false,false,false,false,false,false,false,false,false,true\n" .
|
||||
"#default,_result,,,,,,,,,\n" .
|
||||
",result,table,_start,_stop,_time,_value,_field,_measurement,host,value\n" .
|
||||
",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,12.25\n" .
|
||||
",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,\n";
|
||||
|
||||
$fluxCsvParser = new FluxCsvParser($data);
|
||||
$tables = $fluxCsvParser->parse()->tables;
|
||||
|
||||
$records = $tables[0]->records;
|
||||
|
||||
$this->assertEquals('12.25', $records[0]->values['value']);
|
||||
$this->assertNull($records[1]->values['value']);
|
||||
}
|
||||
|
||||
public function testError()
|
||||
{
|
||||
$data = "#datatype,string,string\n" .
|
||||
"#group,true,true\n" .
|
||||
"#default,,\n" .
|
||||
",error,reference\n" .
|
||||
',failed to create physical plan: invalid time bounds from procedure from: bounds contain zero time,897';
|
||||
|
||||
$fluxCsvParser = new FluxCsvParser($data);
|
||||
|
||||
try {
|
||||
$fluxCsvParser->parse();
|
||||
$this->fail();
|
||||
} catch (FluxQueryError $e) {
|
||||
$this->assertEquals(
|
||||
'failed to create physical plan: invalid time bounds from procedure from: bounds contain zero time',
|
||||
$e->getMessage()
|
||||
);
|
||||
$this->assertEquals(897, $e->getCode());
|
||||
} catch (Exception $e) {
|
||||
$this->fail();
|
||||
}
|
||||
}
|
||||
|
||||
public function testErrorWithoutReference()
|
||||
{
|
||||
$data = "#datatype,string,string\n" .
|
||||
"#group,true,true\n" .
|
||||
"#default,,\n" .
|
||||
",error,reference\n" .
|
||||
',failed to create physical plan: invalid time bounds from procedure from: bounds contain zero time,';
|
||||
|
||||
$fluxCsvParser = new FluxCsvParser($data);
|
||||
|
||||
try {
|
||||
$fluxCsvParser->parse();
|
||||
$this->fail();
|
||||
} catch (FluxQueryError $e) {
|
||||
$this->assertEquals(
|
||||
'failed to create physical plan: invalid time bounds from procedure from: bounds contain zero time',
|
||||
$e->getMessage()
|
||||
);
|
||||
$this->assertEquals(0, $e->getCode());
|
||||
} catch (Exception $e) {
|
||||
$this->fail();
|
||||
}
|
||||
}
|
||||
|
||||
public function testWithoutTableReference()
|
||||
{
|
||||
$data = ",result,table,_start,_stop,_time,_value,_field,_measurement,host,value\n" .
|
||||
",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,12.25\n" .
|
||||
",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,\n";
|
||||
|
||||
$fluxCsvParser = new FluxCsvParser($data);
|
||||
|
||||
try {
|
||||
$fluxCsvParser->parse();
|
||||
$this->fail();
|
||||
} catch (FluxCsvParserException $e) {
|
||||
$this->assertEquals(
|
||||
'Unable to parse CSV response. FluxTable definition was not found.',
|
||||
$e->getMessage()
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
$this->fail();
|
||||
}
|
||||
}
|
||||
|
||||
public function testParserErrorUndefinedOffset()
|
||||
{
|
||||
$data = "#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,double,string,string,string,string,string\n" .
|
||||
"#group,false,false,true,true,false,false,true,true,true,true,true\n" .
|
||||
"#default,_result,,,,,,,,,,\n" .
|
||||
",result,table,_start,_stop,_time,_value,_field,_measurement,channel,device_eui,sensor_eui\n" .
|
||||
",,0,2020-03-27T15:17:00.64917903Z,2020-03-27T16:17:00.64917903Z,2020-03-27T15:17:43.775791768Z,23.4,value,4097,1,2CF7F1201470029C,vs\n" .
|
||||
",,0,2020-03-27T15:17:00.64917903Z,2020-03-27T16:17:00.64917903Z,2020-03-27T15:27:45.894980937Z,22.5,value,4097,1,2CF7F1201470029C,vs\n" .
|
||||
",,0,2020-03-27T15:17:00.64917903Z,2020-03-27T16:17:00.64917903Z,2020-03-27T15:37:50.278735828Z,21.4,value,4097,1,2CF7F1201470029C,vs\n" .
|
||||
",,0,2020-03-27T15:17:00.64917903Z,2020-03-27T16:17:00.64917903Z,2020-03-27T15:47:51.766261407Z,20.3,value,4097,1,2CF7F1201470029C,vs\n" .
|
||||
",,0,2020-03-27T15:17:00.64917903Z,2020-03-27T16:17:00.64917903Z,2020-03-27T15:57:57.475875729Z,18.9,value,4097,1,2CF7F1201470029C,vs\n" .
|
||||
",,0,2020-03-27T15:17:00.64917903Z,2020-03-27T16:17:00.64917903Z,2020-03-27T16:07:59.413550698Z,17.8,value,4097,1,2CF7F1201470029C,vs\n" .
|
||||
"\n" .
|
||||
"#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,double,string,string,string,string,string\n" .
|
||||
"#group,false,false,true,true,false,false,true,true,true,true,true\n" .
|
||||
"#default,_result,,,,,,,,,,\n" .
|
||||
",result,table,_start,_stop,_time,_value,_field,_measurement,channel,device_eui,sensor_eui\n" .
|
||||
",,1,2020-03-27T15:17:00.64917903Z,2020-03-27T16:17:00.64917903Z,2020-03-27T15:43:49.398558429Z,12.3,value,4102,1,2CF7F12014700247,vs\n" .
|
||||
|
||||
"#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,double,string,string,string,string,string\n" .
|
||||
"#group,false,false,true,true,false,false,true,true,true,true,true\n" .
|
||||
"#default,_result,,,,,,,,,,\n" .
|
||||
",result,table,_start,_stop,_time,_value,_field,_measurement,channel,device_eui,sensor_eui\n" .
|
||||
",,2,2020-03-27T15:17:00.64917903Z,2020-03-27T16:17:00.64917903Z,2020-03-27T15:17:43.772929338Z,43.1,value,4098,1,2CF7F1201470029C,vs\n" .
|
||||
",,2,2020-03-27T15:17:00.64917903Z,2020-03-27T16:17:00.64917903Z,2020-03-27T15:27:45.897608471Z,49,value,4098,1,2CF7F1201470029C,vs\n" .
|
||||
",,2,2020-03-27T15:17:00.64917903Z,2020-03-27T16:17:00.64917903Z,2020-03-27T15:37:50.27543528Z,48.2,value,4098,1,2CF7F1201470029C,vs\n" .
|
||||
",,2,2020-03-27T15:17:00.64917903Z,2020-03-27T16:17:00.64917903Z,2020-03-27T15:47:51.769665096Z,44.7,value,4098,1,2CF7F1201470029C,vs\n" .
|
||||
",,2,2020-03-27T15:17:00.64917903Z,2020-03-27T16:17:00.64917903Z,2020-03-27T15:57:57.47339818Z,48.5,value,4098,1,2CF7F1201470029C,vs\n" .
|
||||
",,2,2020-03-27T15:17:00.64917903Z,2020-03-27T16:17:00.64917903Z,2020-03-27T16:07:59.40946618Z,52.3,value,4098,1,2CF7F1201470029C,vs\n" .
|
||||
"\n" .
|
||||
"#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,double,string,string,string,string,string\n" .
|
||||
"#group,false,false,true,true,false,false,true,true,true,true,true\n" .
|
||||
"#default,_result,,,,,,,,,,\n" .
|
||||
",result,table,_start,_stop,_time,_value,_field,_measurement,channel,device_eui,sensor_eui\n" .
|
||||
",,3,2020-03-27T15:17:00.64917903Z,2020-03-27T16:17:00.64917903Z,2020-03-27T15:43:49.39609423Z,30.7,value,4103,1,2CF7F12014700247,vs\n";
|
||||
|
||||
$parser = new FluxCsvParser($data);
|
||||
$tables = $parser->parse()->tables;
|
||||
|
||||
$this->assertEquals(4, sizeof($tables));
|
||||
$this->assertEquals(6, sizeof($tables[0]->records));
|
||||
$this->assertEquals(1, sizeof($tables[1]->records));
|
||||
$this->assertEquals(6, sizeof($tables[2]->records));
|
||||
$this->assertEquals(1, sizeof($tables[3]->records));
|
||||
}
|
||||
|
||||
public function testResponseWithError()
|
||||
{
|
||||
$data = "#datatype,string,long,string,string,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,double,string\n" .
|
||||
"#group,false,false,true,true,true,true,false,false,true\n" .
|
||||
"#default,t1,,,,,,,,\n" .
|
||||
",result,table,_field,_measurement,_start,_stop,_time,_value,tag\n" .
|
||||
",,0,value,python_client_test,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:20:00Z,2,test1\n" .
|
||||
",,0,value,python_client_test,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:21:40Z,2,test1\n" .
|
||||
",,0,value,python_client_test,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:23:20Z,2,test1\n" .
|
||||
",,0,value,python_client_test,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:25:00Z,2,test1\n" .
|
||||
"\n" .
|
||||
"#datatype,string,string\n" .
|
||||
"#group,true,true\n" .
|
||||
"#default,,\n" .
|
||||
",error,reference\n" .
|
||||
",\"engine: unknown field type for value: xyz\",";
|
||||
|
||||
$fluxCsvParser = new FluxCsvParser($data);
|
||||
|
||||
try {
|
||||
$fluxCsvParser->parse();
|
||||
$this->fail();
|
||||
} catch (FluxQueryError $e) {
|
||||
$this->assertEquals(
|
||||
'engine: unknown field type for value: xyz',
|
||||
$e->getMessage()
|
||||
);
|
||||
$this->assertEquals(0, $e->getCode());
|
||||
} catch (Exception $e) {
|
||||
$this->fail();
|
||||
}
|
||||
}
|
||||
|
||||
public function testParseExportFromUserInterface()
|
||||
{
|
||||
$data = "#group,false,false,true,true,true,true,true,true,false,false\n" .
|
||||
"#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,string,string,string,string,double,dateTime:RFC3339\n" .
|
||||
"#default,mean,,,,,,,,,\n" .
|
||||
",result,table,_start,_stop,_field,_measurement,city,location,_value,_time\n" .
|
||||
",,0,1754-06-26T11:30:27.613654848Z,2040-10-27T12:13:46.485Z,temperatureC,weather,London,us-midwest,30,1975-09-01T16:59:54.5Z\n" .
|
||||
",,1,1754-06-26T11:30:27.613654848Z,2040-10-27T12:13:46.485Z,temperatureF,weather,London,us-midwest,86,1975-09-01T16:59:54.5Z\n";
|
||||
|
||||
$parser = new FluxCsvParser($data);
|
||||
$tables = $parser->parse()->tables;
|
||||
|
||||
$this->assertEquals(2, sizeof($tables));
|
||||
$this->assertEquals(1, sizeof($tables[0]->records));
|
||||
$this->assertFalse($tables[0]->columns[0]->group);
|
||||
$this->assertFalse($tables[0]->columns[1]->group);
|
||||
$this->assertTrue($tables[0]->columns[2]->group);
|
||||
$this->assertEquals(1, sizeof($tables[1]->records));
|
||||
}
|
||||
|
||||
public function testParseWithoutDatatype()
|
||||
{
|
||||
$data = ",result,table,_start,_stop,_field,_measurement,host,region,_value2,value1,value_str\n" .
|
||||
",,0,1677-09-21T00:12:43.145224192Z,2018-07-16T11:21:02.547596934Z,free,mem,A,west,121,11,test\n" .
|
||||
",,1,1677-09-21T00:12:43.145224192Z,2018-07-16T11:21:02.547596934Z,free,mem,A,west,121,11,test\n";
|
||||
|
||||
$parser = new FluxCsvParser($data, false, "only_names");
|
||||
$tables = $parser->parse()->tables;
|
||||
|
||||
$this->assertEquals(2, sizeof($tables));
|
||||
$this->assertEquals(11, sizeof($tables[0]->columns));
|
||||
$this->assertEquals(1, sizeof($tables[0]->records));
|
||||
$this->assertEquals(11, sizeof($tables[0]->records[0]->values));
|
||||
$this->assertEquals("0", $tables[0]->records[0]->values['table']);
|
||||
$this->assertEquals("11", $tables[0]->records[0]->values['value1']);
|
||||
$this->assertEquals("west", $tables[0]->records[0]->values['region']);
|
||||
}
|
||||
|
||||
public function testRecordDoesntContainsKey()
|
||||
{
|
||||
$data = "#group,false,false,true,true,true,true,true,true,false,false\n" .
|
||||
"#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,string,string,string,string,double,dateTime:RFC3339\n" .
|
||||
"#default,mean,,,,,,,,,\n" .
|
||||
",result,table,_start,_stop,_field,_measurement,city,location,value,_time\n" .
|
||||
",,0,1754-06-26T11:30:27.613654848Z,2040-10-27T12:13:46.485Z,temperatureC,weather,London,us-midwest,30,1975-09-01T16:59:54.5Z\n";
|
||||
|
||||
$parser = new FluxCsvParser($data);
|
||||
$tables = $parser->parse()->tables;
|
||||
$record = $tables[0]->records[0];
|
||||
|
||||
try {
|
||||
$record->getValue();
|
||||
$this->fail("Expected exception");
|
||||
} catch (Exception $e) {
|
||||
$this->assertEquals("Record doesn't contain column named '_value'. " .
|
||||
"Columns: 'result, table, _start, _stop, _field, _measurement, city, location, value, _time'.", $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function testParseInfinity()
|
||||
{
|
||||
$data = "#group,false,false,true,true,true,true,true,true,true,true,false,false
|
||||
#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,string,string,string,string,string,string,double,double
|
||||
#default,_result,,,,,,,,,,,
|
||||
,result,table,_start,_stop,_field,_measurement,language,license,name,owner,le,_value
|
||||
,,0,2021-06-23T06:50:11.897825012Z,2021-06-25T06:50:11.897825012Z,stars,github_repository,C#,MIT License,influxdb-client-csharp,influxdata,0,0
|
||||
,,0,2021-06-23T06:50:11.897825012Z,2021-06-25T06:50:11.897825012Z,stars,github_repository,C#,MIT License,influxdb-client-csharp,influxdata,10,0
|
||||
,,0,2021-06-23T06:50:11.897825012Z,2021-06-25T06:50:11.897825012Z,stars,github_repository,C#,MIT License,influxdb-client-csharp,influxdata,20,0
|
||||
,,0,2021-06-23T06:50:11.897825012Z,2021-06-25T06:50:11.897825012Z,stars,github_repository,C#,MIT License,influxdb-client-csharp,influxdata,30,0
|
||||
,,0,2021-06-23T06:50:11.897825012Z,2021-06-25T06:50:11.897825012Z,stars,github_repository,C#,MIT License,influxdb-client-csharp,influxdata,40,0
|
||||
,,0,2021-06-23T06:50:11.897825012Z,2021-06-25T06:50:11.897825012Z,stars,github_repository,C#,MIT License,influxdb-client-csharp,influxdata,50,0
|
||||
,,0,2021-06-23T06:50:11.897825012Z,2021-06-25T06:50:11.897825012Z,stars,github_repository,C#,MIT License,influxdb-client-csharp,influxdata,60,0
|
||||
,,0,2021-06-23T06:50:11.897825012Z,2021-06-25T06:50:11.897825012Z,stars,github_repository,C#,MIT License,influxdb-client-csharp,influxdata,70,0
|
||||
,,0,2021-06-23T06:50:11.897825012Z,2021-06-25T06:50:11.897825012Z,stars,github_repository,C#,MIT License,influxdb-client-csharp,influxdata,80,0
|
||||
,,0,2021-06-23T06:50:11.897825012Z,2021-06-25T06:50:11.897825012Z,stars,github_repository,C#,MIT License,influxdb-client-csharp,influxdata,90,0
|
||||
,,0,2021-06-23T06:50:11.897825012Z,2021-06-25T06:50:11.897825012Z,stars,github_repository,C#,MIT License,influxdb-client-csharp,influxdata,+Inf,15
|
||||
,,0,2021-06-23T06:50:11.897825012Z,2021-06-25T06:50:11.897825012Z,stars,github_repository,C#,MIT License,influxdb-client-csharp,influxdata,-Inf,15
|
||||
|
||||
";
|
||||
|
||||
$parser = new FluxCsvParser($data);
|
||||
$tables = $parser->parse()->tables;
|
||||
|
||||
$this->assertEquals(1, sizeof($tables));
|
||||
$this->assertEquals(12, sizeof($tables[0]->records));
|
||||
$this->assertEquals(INF, $tables[0]->records[10]->values['le']);
|
||||
$this->assertEquals(-INF, $tables[0]->records[11]->values['le']);
|
||||
}
|
||||
|
||||
public function testParseDuplicateColumnNames()
|
||||
{
|
||||
$data = "#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,string,string,double
|
||||
#group,false,false,true,true,false,true,true,false
|
||||
#default,_result,,,,,,,
|
||||
,result,table,_start,_stop,_time,_measurement,location,result
|
||||
,,0,2022-09-13T06:14:40.469404272Z,2022-09-13T06:24:40.469404272Z,2022-09-13T06:24:33.746Z,my_measurement,Prague,25.3
|
||||
,,0,2022-09-13T06:14:40.469404272Z,2022-09-13T06:24:40.469404272Z,2022-09-13T06:24:39.299Z,my_measurement,Prague,25.3
|
||||
,,0,2022-09-13T06:14:40.469404272Z,2022-09-13T06:24:40.469404272Z,2022-09-13T06:24:40.454Z,my_measurement,Prague,25.3
|
||||
";
|
||||
|
||||
$parser = new FluxCsvParser($data);
|
||||
$tables = $parser->parse()->tables;
|
||||
|
||||
$this->assertEquals(1, sizeof($tables));
|
||||
$this->assertEquals(3, sizeof($tables[0]->records));
|
||||
$this->assertEquals(8, sizeof($tables[0]->columns));
|
||||
$this->assertEquals(7, sizeof($tables[0]->records[0]->values));
|
||||
$this->assertEquals(8, sizeof($tables[0]->records[0]->row));
|
||||
$this->assertEquals(25.3, $tables[0]->records[0]->row[7]);
|
||||
}
|
||||
|
||||
private function assertColumns(array $columnHeaders, array $values)
|
||||
{
|
||||
$i = 0;
|
||||
foreach ($values as $value) {
|
||||
$this->assertEquals($value, $columnHeaders[$i]->group, "column assert '" . $columnHeaders[$i]->label . "'");
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
private function assertMultipleRecords(array $tables)
|
||||
{
|
||||
#Record 1
|
||||
$tableRecords = $tables[0]->records;
|
||||
$this->assertEquals(1, sizeof($tableRecords));
|
||||
|
||||
$values = ['table' => 0, 'host' => 'A', 'region' => 'west', 'value1' => 11, '_value2' => 121,
|
||||
'value_str' => 'test'];
|
||||
|
||||
$this->assertRecord($tableRecords[0], $values, 11);
|
||||
|
||||
#Record 2
|
||||
$tableRecords = $tables[1]->records;
|
||||
$this->assertEquals(1, sizeof($tableRecords));
|
||||
|
||||
$values = ['table' => 1, 'host' => 'B', 'region' => 'west', 'value1' => 22, '_value2' => 484,
|
||||
'value_str' => 'test'];
|
||||
|
||||
$this->assertRecord($tableRecords[0], $values, 11);
|
||||
|
||||
#Record 3
|
||||
$tableRecords = $tables[2]->records;
|
||||
$this->assertEquals(1, sizeof($tableRecords));
|
||||
|
||||
$values = ['table' => 2, 'host' => 'A', 'region' => 'west', 'value1' => 38, '_value2' => 1444,
|
||||
'value_str' => 'test'];
|
||||
|
||||
$this->assertRecord($tableRecords[0], $values, 11);
|
||||
|
||||
#Record 4
|
||||
$tableRecords = $tables[3]->records;
|
||||
$this->assertEquals(1, sizeof($tableRecords));
|
||||
|
||||
$values = ['table' => 3, 'host' => 'A', 'region' => 'west', 'value1' => 49, '_value2' => 2401,
|
||||
'value_str' => 'test'];
|
||||
|
||||
$this->assertRecord($tableRecords[0], $values, 11);
|
||||
}
|
||||
|
||||
private function assertRecord(FluxRecord $fluxRecord, array $values, $size = 0, $value = null)
|
||||
{
|
||||
foreach ($values as $key => $val) {
|
||||
$this->assertEquals($values[$key], $fluxRecord->values[$key]);
|
||||
}
|
||||
|
||||
if ($value == null) {
|
||||
$this->assertNull($value);
|
||||
} else {
|
||||
$this->assertEquals($value, $fluxRecord->getValue());
|
||||
}
|
||||
$this->assertEquals($size, sizeof($fluxRecord->values));
|
||||
}
|
||||
|
||||
private function parseTime(string $timestamp)
|
||||
{
|
||||
//TODO datetime parsing
|
||||
return $timestamp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
use InfluxDB2\ApiException;
|
||||
use InfluxDB2\Model\BucketRetentionRules;
|
||||
use InfluxDB2\Model\PostBucketRequest;
|
||||
use InfluxDB2\ObjectSerializer;
|
||||
use InfluxDB2\Service\BucketsService;
|
||||
use InfluxDB2\Service\HealthService;
|
||||
|
||||
require_once('IntegrationBaseTestCase.php');
|
||||
|
||||
/**
|
||||
* @group integration
|
||||
*/
|
||||
class ITBucketServiceTest extends IntegrationBaseTestCase
|
||||
{
|
||||
public function testHealthService()
|
||||
{
|
||||
$healthService = $this->client->createService(HealthService::class);
|
||||
$healthCheck = $healthService->getHealth();
|
||||
self::assertEquals("influxdb", $healthCheck->getName());
|
||||
self::assertEquals("ready for queries and writes", $healthCheck->getMessage());
|
||||
}
|
||||
|
||||
public function testFixNanosTimeSerialization()
|
||||
{
|
||||
self::assertEquals(
|
||||
"2020-09-18T08:03:48.12345Z",
|
||||
ObjectSerializer::fixDatetimeNanos("2020-09-18T08:03:48.12345Z")
|
||||
);
|
||||
|
||||
self::assertEquals(
|
||||
"2020-09-18T08:03:48.123456Z",
|
||||
ObjectSerializer::fixDatetimeNanos("2020-09-18T08:03:48.123456Z")
|
||||
);
|
||||
|
||||
self::assertEquals(
|
||||
"2020-09-18T08:03:48.1234567Z",
|
||||
ObjectSerializer::fixDatetimeNanos("2020-09-18T08:03:48.1234567Z")
|
||||
);
|
||||
|
||||
self::assertEquals(
|
||||
"2020-09-18T08:03:48.12345678Z",
|
||||
ObjectSerializer::fixDatetimeNanos("2020-09-18T08:03:48.12345678Z")
|
||||
);
|
||||
|
||||
self::assertEquals(
|
||||
"2020-09-18T08:03:48.12345678Z",
|
||||
ObjectSerializer::fixDatetimeNanos("2020-09-18T08:03:48.123456789Z")
|
||||
);
|
||||
|
||||
self::assertEquals(
|
||||
"2020-09-18T08:03:48.12345678Z",
|
||||
ObjectSerializer::fixDatetimeNanos("2020-09-18T08:03:48.1234567899Z")
|
||||
);
|
||||
|
||||
self::assertEquals(
|
||||
"2021-09-29T06:32:56Z",
|
||||
ObjectSerializer::fixDatetimeNanos("2021-09-29T06:32:56Z")
|
||||
);
|
||||
}
|
||||
|
||||
public function testBucketService()
|
||||
{
|
||||
/** @var BucketsService $bucketsService */
|
||||
$bucketsService = $this->client->createService(BucketsService::class);
|
||||
$buckets = $bucketsService->getBuckets(null, null, 100, null)->getBuckets();
|
||||
foreach ($buckets as $bucket) {
|
||||
self::assertNotEmpty($bucket->getName());
|
||||
self::assertNotEmpty($bucket->getId());
|
||||
}
|
||||
}
|
||||
|
||||
public function testBucketServiceCreateBucket()
|
||||
{
|
||||
/** @var BucketsService $bucketsService */
|
||||
$bucketsService = $this->client->createService(BucketsService::class);
|
||||
|
||||
$rule = new BucketRetentionRules();
|
||||
$rule->setEverySeconds(3600);
|
||||
|
||||
$bucketName = $this->generateBucketName();
|
||||
$bucketRequest = new PostBucketRequest();
|
||||
$bucketRequest->setName($bucketName)
|
||||
->setRetentionRules([$rule])
|
||||
->setOrgId($this->findMyOrg()->getId());
|
||||
|
||||
//create bucket
|
||||
$respBucket = $bucketsService->postBuckets($bucketRequest);
|
||||
print $respBucket;
|
||||
self::assertEquals($bucketName, $respBucket->getName());
|
||||
|
||||
//find bucket
|
||||
$buckets = $bucketsService->getBuckets(null, null, 100, null)->getBuckets();
|
||||
$findBucket = null;
|
||||
foreach ($buckets as $bucket) {
|
||||
self::assertNotEmpty($bucket->getName());
|
||||
self::assertNotEmpty($bucket->getId());
|
||||
if ($bucket->getId() == $respBucket->getId()) {
|
||||
$findBucket = $bucket;
|
||||
}
|
||||
}
|
||||
self::assertNotNull($findBucket);
|
||||
|
||||
//delete bucket
|
||||
$bucketsService->deleteBucketsID($findBucket->getId());
|
||||
|
||||
//verify bucket deleted
|
||||
$this->expectException(ApiException::class);
|
||||
$this->expectExceptionCode(404);
|
||||
$this->expectExceptionMessage("bucket not found");
|
||||
$bucketsService->getBucketsID($findBucket->getId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use InfluxDB2\Model\TaskCreateRequest;
|
||||
use InfluxDB2\Service\TasksService;
|
||||
|
||||
require_once('IntegrationBaseTestCase.php');
|
||||
|
||||
/**
|
||||
* @group integration
|
||||
*/
|
||||
class ITTaskServiceTest extends IntegrationBaseTestCase
|
||||
{
|
||||
public function testCreateTask()
|
||||
{
|
||||
/** @var TasksService $taskService */
|
||||
$taskService = $this->client->createService(TasksService::class);
|
||||
|
||||
$flux = "option task = {
|
||||
name: \"task-name\",
|
||||
every: 6h
|
||||
}
|
||||
from(bucket: \"telegraf\") |> range(start: -1h)
|
||||
";
|
||||
|
||||
$taskCreateRequest = new TaskCreateRequest();
|
||||
$taskCreateRequest
|
||||
->setFlux($flux)
|
||||
->setOrgId($this->findMyOrg()->getId());
|
||||
|
||||
$task = $taskService->postTasks($taskCreateRequest);
|
||||
|
||||
self::assertEquals("task-name", $task->getName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
use InfluxDB2\Service\UsersService;
|
||||
|
||||
require_once('IntegrationBaseTestCase.php');
|
||||
|
||||
/**
|
||||
* @group integration
|
||||
*/
|
||||
class ITUsersServiceTest extends IntegrationBaseTestCase
|
||||
{
|
||||
public function testUserService()
|
||||
{
|
||||
/** @var UsersService $usersService */
|
||||
$usersService = $this->client->createService(UsersService::class);
|
||||
$users = $usersService->getUsers()->getUsers();
|
||||
foreach ($users as $user) {
|
||||
self::assertNotEmpty($user->getName());
|
||||
self::assertNotEmpty($user->getId());
|
||||
self::assertNotEmpty($user->getLinks()->getSelf());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
use InfluxDB2\Client;
|
||||
use InfluxDB2\Model\Organization;
|
||||
use InfluxDB2\Model\WritePrecision;
|
||||
use InfluxDB2\Service\OrganizationsService;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class IntegrationBaseTestCase extends TestCase
|
||||
{
|
||||
public $client;
|
||||
public $options;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->options = [
|
||||
"url" => "http://localhost:8086",
|
||||
"token" => "my-token",
|
||||
"bucket" => "my-bucket",
|
||||
"precision" => WritePrecision::NS,
|
||||
"org" => "my-org",
|
||||
"debug" => false
|
||||
];
|
||||
$this->client = new Client($this->options);
|
||||
}
|
||||
|
||||
|
||||
public function findMyOrg(): ?Organization
|
||||
{
|
||||
/** @var OrganizationsService $orgService */
|
||||
$orgService = $this->client->createService(OrganizationsService::class);
|
||||
$orgs = $orgService->getOrgs()->getOrgs();
|
||||
foreach ($orgs as $org) {
|
||||
if ($org->getName() == $this->options["org"]) {
|
||||
return $org;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function generateBucketName()
|
||||
{
|
||||
return "IT-php-bucket-" . microtime();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB2Test;
|
||||
|
||||
require_once('BasicTest.php');
|
||||
|
||||
/**
|
||||
* Class InvokableScriptsApiTest
|
||||
* @package InfluxDB2Test
|
||||
*/
|
||||
class InvokableScriptsApiTest extends BasicTest
|
||||
{
|
||||
public function testCreateInstance()
|
||||
{
|
||||
$invokableScriptsApi = $this->client->createInvokableScriptsApi();
|
||||
|
||||
$this->assertNotNull($invokableScriptsApi);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB2Test;
|
||||
|
||||
use InfluxDB2\Client;
|
||||
use InfluxDB2\Model\WritePrecision;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class PointSettingsTest extends TestCase
|
||||
{
|
||||
private const ID_TAG = "132-987-655";
|
||||
private const CUSTOMER_TAG = "California Miner";
|
||||
|
||||
/** @var Client */
|
||||
private $client;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->client = new Client([
|
||||
"url" => "http://localhost:8086",
|
||||
"token" => "my-token",
|
||||
"bucket" => "my-bucket",
|
||||
"precision" => WritePrecision::NS,
|
||||
"org" => "my-org",
|
||||
"tags" => ['id' => PointSettingsTest::ID_TAG]
|
||||
]);
|
||||
}
|
||||
|
||||
public function testPointSettings()
|
||||
{
|
||||
$writeApi = $this->client->createWriteApi(null, ['customer' => PointSettingsTest::CUSTOMER_TAG]);
|
||||
|
||||
$defaultTags = $writeApi->pointSettings->getDefaultTags();
|
||||
|
||||
$this->assertEquals(PointSettingsTest::ID_TAG, $defaultTags['id']);
|
||||
$this->assertEquals(PointSettingsTest::CUSTOMER_TAG, $defaultTags['customer']);
|
||||
}
|
||||
|
||||
public function testPointSettingsWithAdd()
|
||||
{
|
||||
putenv("data_center=LA");
|
||||
|
||||
$writeApi = $this->client->createWriteApi();
|
||||
|
||||
$writeApi->pointSettings->addDefaultTag('customer', PointSettingsTest::CUSTOMER_TAG);
|
||||
|
||||
$defaultTags = $writeApi->pointSettings->getDefaultTags();
|
||||
|
||||
$this->assertEquals(PointSettingsTest::ID_TAG, $defaultTags['id']);
|
||||
$this->assertEquals(PointSettingsTest::CUSTOMER_TAG, $defaultTags['customer']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB2Test;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeImmutable;
|
||||
use InfluxDB2\Model\WritePrecision;
|
||||
use InfluxDB2\Point;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class PointTest extends TestCase
|
||||
{
|
||||
public function testToLineProtocol()
|
||||
{
|
||||
$pointArgs = new Point(
|
||||
'h2o',
|
||||
array('host' => 'aws', 'region' => 'us'),
|
||||
array('level' => 5, 'saturation' => '99%'),
|
||||
123
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'h2o,host=aws,region=us level=5i,saturation="99%" 123',
|
||||
$pointArgs->toLineProtocol()
|
||||
);
|
||||
|
||||
$pointArray = Point::fromArray(array('name' => 'h2o',
|
||||
'tags' => array('host' => 'aws', 'region' => 'us'),
|
||||
'fields' => array('level' => 5, 'saturation' => '99%'),
|
||||
'time' => 123));
|
||||
|
||||
$this->assertEquals(
|
||||
'h2o,host=aws,region=us level=5i,saturation="99%" 123',
|
||||
$pointArray->toLineProtocol()
|
||||
);
|
||||
}
|
||||
|
||||
public function testMeasurementEscape()
|
||||
{
|
||||
$point = new Point('h2 o 2', array('location' => 'europe'), array('level' => 2));
|
||||
$this->assertEquals('h2\\ o\\ 2,location=europe level=2i', $point->toLineProtocol());
|
||||
|
||||
$point = new Point('h2,o', array('location' => 'europe'), array('level' => 2));
|
||||
$this->assertEquals('h2\\,o,location=europe level=2i', $point->toLineProtocol());
|
||||
}
|
||||
|
||||
public function testEmptyKey()
|
||||
{
|
||||
$point = Point::measurement('h2o')
|
||||
->addField('level', 2)
|
||||
->addTag('location', 'europe')
|
||||
->addTag('', 'warn');
|
||||
|
||||
$this->assertEquals('h2o,location=europe level=2i', $point->toLineProtocol());
|
||||
}
|
||||
|
||||
public function testEmptyValue()
|
||||
{
|
||||
$point = Point::measurement('h2o')
|
||||
->addField('level', 2)
|
||||
->addTag('location', 'europe')
|
||||
->addTag('log', '');
|
||||
|
||||
$this->assertEquals('h2o,location=europe level=2i', $point->toLineProtocol());
|
||||
}
|
||||
|
||||
public function testTagEscapingKeyAndValue()
|
||||
{
|
||||
$point = Point::measurement("h\n2\ro\t_data")
|
||||
->addTag("new\nline", "new\nline")
|
||||
->addTag("carriage\rreturn", "carriage\nreturn")
|
||||
->addTag("t\tab", "t\tab")
|
||||
->addField("level", 2);
|
||||
|
||||
$this->assertEquals(
|
||||
"h\\n2\\ro\\t_data,carriage\\rreturn=carriage\\nreturn,new\\nline=new\\nline,t\\tab=t\\tab level=2i",
|
||||
$point->toLineProtocol()
|
||||
);
|
||||
}
|
||||
|
||||
public function testEqualSignEscaping()
|
||||
{
|
||||
$point = Point::measurement("h=2o")
|
||||
->addTag("l=ocation", "e=urope")
|
||||
->addField("l=evel", 2);
|
||||
|
||||
$this->assertEquals("h=2o,l\\=ocation=e\\=urope l\\=evel=2i", $point->toLineProtocol());
|
||||
}
|
||||
|
||||
public function testOverrideTagAndField()
|
||||
{
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addTag('location', 'europe2')
|
||||
->addField('level', 1)
|
||||
->addField('level', 2)
|
||||
->addField('level', 3);
|
||||
|
||||
$this->assertEquals('h2o,location=europe2 level=3i', $point->toLineProtocol());
|
||||
}
|
||||
|
||||
public function testFieldTypes()
|
||||
{
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('tag_b', 'b')
|
||||
->addTag('tag_a', 'a')
|
||||
->addField('n1', -2)
|
||||
->addField('n2', 10)
|
||||
->addField('n3', 9223372036854775807)
|
||||
->addField('n4', 5.5)
|
||||
->addField('bool', true)
|
||||
->addField('string', 'string value');
|
||||
|
||||
$expected = 'h2o,tag_a=a,tag_b=b bool=true,n1=-2i,n2=10i,n3=9223372036854775807i,n4=5.5,string="string value"';
|
||||
$this->assertEquals($expected, $point->toLineProtocol());
|
||||
}
|
||||
|
||||
public function testFieldNullValue()
|
||||
{
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2)
|
||||
->addField('warning', null);
|
||||
|
||||
$this->assertEquals('h2o,location=europe level=2i', $point->toLineProtocol());
|
||||
}
|
||||
|
||||
public function testFieldEscape()
|
||||
{
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 'string esc"ape value');
|
||||
|
||||
$this->assertEquals('h2o,location=europe level="string esc\"ape value"', $point->toLineProtocol());
|
||||
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 'string esc\\ape value');
|
||||
|
||||
$this->assertEquals('h2o,location=europe level="string esc\\\\ape value"', $point->toLineProtocol());
|
||||
}
|
||||
|
||||
public function testTime()
|
||||
{
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2)
|
||||
->time(123, WritePrecision::NS);
|
||||
|
||||
$this->assertEquals('h2o,location=europe level=2i 123', $point->toLineProtocol());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDateTime
|
||||
*/
|
||||
public function testTimeFormatting($time)
|
||||
{
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2)
|
||||
->time($time, WritePrecision::MS);
|
||||
|
||||
$this->assertEquals('h2o,location=europe level=2i 1444897215000', $point->toLineProtocol());
|
||||
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2)
|
||||
->time($time, WritePrecision::S);
|
||||
|
||||
$this->assertEquals('h2o,location=europe level=2i 1444897215', $point->toLineProtocol());
|
||||
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2)
|
||||
->time($time, WritePrecision::US);
|
||||
|
||||
$this->assertEquals('h2o,location=europe level=2i 1444897215000000', $point->toLineProtocol());
|
||||
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2)
|
||||
->time($time, WritePrecision::NS);
|
||||
|
||||
$this->assertEquals('h2o,location=europe level=2i 1444897215000000000', $point->toLineProtocol());
|
||||
}
|
||||
|
||||
public function providerDateTime()
|
||||
{
|
||||
return [
|
||||
[
|
||||
(new DateTime())
|
||||
->setDate(2015, 10, 15)
|
||||
->setTime(8, 20, 15)
|
||||
],
|
||||
[
|
||||
(new DateTimeImmutable())
|
||||
->setDate(2015, 10, 15)
|
||||
->setTime(8, 20, 15)
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function testTimeFormattingDefault()
|
||||
{
|
||||
$time = new DateTime();
|
||||
$time->setDate(2015, 10, 15);
|
||||
$time->setTime(8, 20, 15);
|
||||
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2)
|
||||
->time($time);
|
||||
|
||||
$this->assertEquals('h2o,location=europe level=2i 1444897215000000000', $point->toLineProtocol());
|
||||
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2)
|
||||
->time($time, null);
|
||||
|
||||
$this->assertEquals('h2o,location=europe level=2i 1444897215000000000', $point->toLineProtocol());
|
||||
}
|
||||
|
||||
public function testTimeString()
|
||||
{
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2)
|
||||
->time('123');
|
||||
|
||||
$this->assertEquals('h2o,location=europe level=2i 123', $point->toLineProtocol());
|
||||
}
|
||||
|
||||
public function testTimeFloat()
|
||||
{
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2)
|
||||
->time(102030405060.24);
|
||||
|
||||
$this->assertEquals('h2o,location=europe level=2i 102030405060', $point->toLineProtocol());
|
||||
}
|
||||
|
||||
public function testUtf8()
|
||||
{
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'Přerov')
|
||||
->addField('level', 2)
|
||||
->time(123);
|
||||
|
||||
$this->assertEquals('h2o,location=Přerov level=2i 123', $point->toLineProtocol());
|
||||
}
|
||||
|
||||
public function testWithoutTags()
|
||||
{
|
||||
$point = Point::measurement('h2o')
|
||||
->addField('level', 2)
|
||||
->time(123);
|
||||
|
||||
$this->assertEquals('h2o level=2i 123', $point->toLineProtocol());
|
||||
}
|
||||
|
||||
public function testWithoutFields()
|
||||
{
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->time(123);
|
||||
|
||||
$this->assertNull($point->toLineProtocol());
|
||||
}
|
||||
|
||||
public function testFromArrayWithoutName()
|
||||
{
|
||||
$pointArray = Point::fromArray(array(
|
||||
'tags' => array('host' => 'aws', 'region' => 'us'),
|
||||
'fields' => array('level' => 5, 'saturation' => '99%'),
|
||||
'time' => 123));
|
||||
|
||||
$this->assertNull($pointArray);
|
||||
}
|
||||
|
||||
public function testTagNotString()
|
||||
{
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addTag('tag_not_string', [])
|
||||
->addTag('tag_not_null', null)
|
||||
->addField('level', 2);
|
||||
|
||||
$this->assertEquals('h2o,location=europe level=2i', $point->toLineProtocol());
|
||||
}
|
||||
}
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB2Test;
|
||||
|
||||
use DateTime;
|
||||
use InfluxDB2\Client;
|
||||
use InfluxDB2\Model\WritePrecision;
|
||||
use InfluxDB2\Point;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @group integration
|
||||
*/
|
||||
class QueryApiIntegrationTest extends TestCase
|
||||
{
|
||||
private $client;
|
||||
private $writeApi;
|
||||
private $queryApi;
|
||||
|
||||
/**
|
||||
* @before
|
||||
*/
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->client = new Client([
|
||||
"url" => "http://localhost:8086",
|
||||
"token" => "my-token",
|
||||
"bucket" => "my-bucket",
|
||||
"precision" => WritePrecision::NS,
|
||||
"org" => "my-org",
|
||||
"debug" => false
|
||||
]);
|
||||
$this->writeApi = $this->client->createWriteApi();
|
||||
$this->queryApi = $this->client->createQueryApi();
|
||||
}
|
||||
|
||||
public function testExistsApi()
|
||||
{
|
||||
$this->assertNotNull($this->writeApi);
|
||||
$this->assertNotNull($this->queryApi);
|
||||
}
|
||||
|
||||
public function testQueryRaw()
|
||||
{
|
||||
$now = new DateTime();
|
||||
$measurement = 'h2o_query_' . $now->getTimestamp();
|
||||
|
||||
$query = $this->prepareData($measurement, $now);
|
||||
print $query;
|
||||
|
||||
$result = $this->queryApi->queryRaw($query);
|
||||
|
||||
$this->assertStringContainsString(',result,table,_start,_stop,_time,_value,_field,_measurement,location', $result);
|
||||
$this->assertStringContainsString($measurement, $result);
|
||||
}
|
||||
|
||||
public function testQuery()
|
||||
{
|
||||
$now = new DateTime();
|
||||
$measurement = 'h2o_query_' . $now->getTimestamp();
|
||||
$query = $this->prepareData($measurement, $now);
|
||||
print $query;
|
||||
|
||||
$result = $this->queryApi->query($query);
|
||||
|
||||
$this->assertNotNull($result);
|
||||
$this->assertEquals(1, sizeof($result));
|
||||
$records = $result[0]->records;
|
||||
$this->assertEquals(1, sizeof($records));
|
||||
$record = $records[0];
|
||||
$this->assertEquals($measurement, $record->getMeasurement());
|
||||
$this->assertEquals('europe', $record->values['location']);
|
||||
$this->assertEquals(2, $record->getValue());
|
||||
$this->assertEquals(0, $record->table);
|
||||
$this->assertEquals(0, $record->values['table']);
|
||||
$this->assertEquals('level', $record->getField());
|
||||
}
|
||||
|
||||
public function testWriteQueryNewLine()
|
||||
{
|
||||
$measurement = 'h2o_QueryNewLine_' . (new DateTime())->getTimestamp();
|
||||
|
||||
$this->writeApi->write(Point::measurement($measurement)
|
||||
->addTag('location', 'europe')
|
||||
->addField('value', "some \n value"));
|
||||
|
||||
$result = $this->queryApi->query('from(bucket: "my-bucket") |> range(start: 0)
|
||||
|> filter(fn: (r) => r._measurement == "' . $measurement . '")');
|
||||
|
||||
$this->assertNotNull($result);
|
||||
$this->assertEquals(1, sizeof($result));
|
||||
$records = $result[0]->records;
|
||||
$this->assertEquals(1, sizeof($records));
|
||||
$record = $records[0];
|
||||
|
||||
$this->assertEquals("some \r\n value", $record->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $measurement
|
||||
* @param DateTime $now
|
||||
* @return string
|
||||
*/
|
||||
public function prepareData(string $measurement, DateTime $now): string
|
||||
{
|
||||
$this->writeApi->write(Point::measurement($measurement)
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2)
|
||||
->time($now, WritePrecision::US));
|
||||
|
||||
$query = 'from(bucket: "my-bucket") |> range(start: 0)
|
||||
|> filter(fn: (r) => r._measurement == "' . $measurement . '")';
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB2Test;
|
||||
|
||||
use DateTime;
|
||||
use InfluxDB2\Client;
|
||||
use InfluxDB2\Model\WritePrecision;
|
||||
use InfluxDB2\Point;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @group integration
|
||||
*/
|
||||
class QueryApiStreamTest extends TestCase
|
||||
{
|
||||
private $client;
|
||||
private $writeApi;
|
||||
private $queryApi;
|
||||
private $now;
|
||||
|
||||
/**
|
||||
* @before
|
||||
*/
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->client = new Client([
|
||||
"url" => "http://localhost:8086",
|
||||
"token" => "my-token",
|
||||
"bucket" => "my-bucket",
|
||||
"precision" => WritePrecision::NS,
|
||||
"org" => "my-org",
|
||||
"debug" => false
|
||||
]);
|
||||
|
||||
$this->writeApi = $this->client->createWriteApi();
|
||||
$this->queryApi = $this->client->createQueryApi();
|
||||
|
||||
$this->now = new DateTime();
|
||||
}
|
||||
|
||||
public function testQueryStream()
|
||||
{
|
||||
$measurement = 'h2o_query_stream' . $this->now->format('Y-m-d-H-i-s');
|
||||
$this->write(10, $measurement);
|
||||
|
||||
$query = 'from(bucket: "my-bucket") |> range(start: -1m, stop: now()) '
|
||||
. '|> filter(fn: (r) => r._measurement == "' . $measurement . '")';
|
||||
|
||||
$count = 0;
|
||||
|
||||
$parser = $this->queryApi->queryStream($query);
|
||||
|
||||
foreach ($parser->each() as $record) {
|
||||
$this->assertNotNull($record);
|
||||
|
||||
$this->assertEquals($measurement, $record->getMeasurement());
|
||||
$this->assertEquals('europe', $record->values['location']);
|
||||
$this->assertEquals($count, $record->getValue());
|
||||
$this->assertEquals('level', $record->getField());
|
||||
|
||||
$count++;
|
||||
}
|
||||
|
||||
$this->assertEquals(10, $count);
|
||||
}
|
||||
|
||||
public function testQueryStreamBreak()
|
||||
{
|
||||
$measurement = 'h2o_query_stream_break' . $this->now->format('Y-m-d-H-i-s');
|
||||
$this->write(20, $measurement);
|
||||
|
||||
$query = 'from(bucket: "my-bucket") |> range(start: -1m, stop: now()) '
|
||||
. '|> filter(fn: (r) => r._measurement == "' . $measurement . '")';
|
||||
|
||||
$count = 0;
|
||||
|
||||
$parser = $this->queryApi->queryStream($query);
|
||||
|
||||
$records = [];
|
||||
|
||||
$this->assertFalse($parser->closed);
|
||||
|
||||
foreach ($parser->each() as $record) {
|
||||
if ($count >= 5) {
|
||||
break;
|
||||
}
|
||||
|
||||
$records[] = $record;
|
||||
|
||||
$count++;
|
||||
}
|
||||
|
||||
$this->assertEquals(5, count($records));
|
||||
$this->assertTrue($parser->closed);
|
||||
}
|
||||
|
||||
public function testQueryEmptyData()
|
||||
{
|
||||
$result = $this->queryApi->queryStream(null);
|
||||
|
||||
$this->assertNull($result);
|
||||
}
|
||||
|
||||
private function write($values, $measurement)
|
||||
{
|
||||
for ($ii = 0; $ii < $values; $ii++) {
|
||||
$this->writeApi->write(
|
||||
Point::measurement($measurement)
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', $ii)
|
||||
->time($this->now->getTimestamp() - $values + $ii, WritePrecision::S),
|
||||
WritePrecision::S
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB2Test;
|
||||
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use InfluxDB2\Model\Query;
|
||||
|
||||
require_once('BasicTest.php');
|
||||
|
||||
/**
|
||||
* Class QueryApiTest
|
||||
* @package InfluxDB2Test
|
||||
*/
|
||||
class QueryApiTest extends BasicTest
|
||||
{
|
||||
private const SUCCESS_DATA =
|
||||
"#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,long,string,string,string,string\n"
|
||||
. "#group,false,false,false,false,false,false,false,false,false,true\n" . "#default,_result,,,,,,,,,\n"
|
||||
. ",result,table,_start,_stop,_time,_value,_field,_measurement,host,region\n"
|
||||
. ",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,10,free,mem,A,west\n"
|
||||
. ",,0,1970-01-01T00:00:10Z,1970-01-01T00:00:20Z,1970-01-01T00:00:10Z,20,free,mem,B,west\n"
|
||||
. ",,0,1970-01-01T00:00:20Z,1970-01-01T00:00:30Z,1970-01-01T00:00:20Z,11,free,mem,A,west\n"
|
||||
. ",,0,1970-01-01T00:00:20Z,1970-01-01T00:00:30Z,1970-01-01T00:00:20Z,22,free,mem,B,west";
|
||||
|
||||
public function testQueryRaw()
|
||||
{
|
||||
$this->mockHandler->append(new Response(204, [], QueryApiTest::SUCCESS_DATA));
|
||||
|
||||
$result = $this->queryApi->queryRaw(
|
||||
'from(bucket:"my-bucket") |> range(start: 1970-01-01T00:00:00.000000001Z) |> last()'
|
||||
);
|
||||
|
||||
$this->assertEquals(QueryApiTest::SUCCESS_DATA, $result);
|
||||
}
|
||||
|
||||
public function testQuery()
|
||||
{
|
||||
$this->mockHandler->append(new Response(204, [], QueryApiTest::SUCCESS_DATA));
|
||||
|
||||
$bucket = 'my-bucket';
|
||||
$result = $this->queryApi->query('from(bucket:"' . $bucket
|
||||
. '") |> range(start: 1970-01-01T00:00:00.000000001Z) |> last()');
|
||||
|
||||
$this->assertEquals(1, count($result));
|
||||
$this->assertEquals(4, count($result[0]->records));
|
||||
|
||||
$record = $result[0]->records[0];
|
||||
|
||||
$this->assertEquals('1970-01-01T00:00:10Z', $record->getTime());
|
||||
$this->assertEquals('mem', $record->getMeasurement());
|
||||
$this->assertEquals(10, $record->getValue());
|
||||
$this->assertEquals('free', $record->getField());
|
||||
}
|
||||
|
||||
public function testQueryParameterized()
|
||||
{
|
||||
$this->mockHandler->append(new Response(204, [], QueryApiTest::SUCCESS_DATA));
|
||||
$q = new Query();
|
||||
|
||||
$q->setQuery('from(bucket: params.bucketParam) |> range(start: time(v: params.startParam)) |> last()');
|
||||
|
||||
$today = new DateTime("2021-12-15T11:33:28+00:00");
|
||||
$yesterday = $today->sub(new DateInterval("P1D"));
|
||||
|
||||
$q->setParams([
|
||||
"bucketParam" => "my-bucket",
|
||||
"startParam" => $yesterday
|
||||
]);
|
||||
|
||||
$result = $this->queryApi->query($q);
|
||||
$contents = $this->mockHandler->getLastRequest()->getBody()->getContents();
|
||||
$json = json_decode($contents, true);
|
||||
|
||||
$this->assertEquals("my-bucket", $json["params"]["bucketParam"]);
|
||||
$this->assertEquals('2021-12-14T11:33:28+00:00', $json["params"]["startParam"]);
|
||||
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertCount(4, $result[0]->records);
|
||||
|
||||
$record = $result[0]->records[0];
|
||||
|
||||
$this->assertEquals('1970-01-01T00:00:10Z', $record->getTime());
|
||||
$this->assertEquals('mem', $record->getMeasurement());
|
||||
$this->assertEquals(10, $record->getValue());
|
||||
$this->assertEquals('free', $record->getField());
|
||||
}
|
||||
|
||||
public function testQueryRawEmptyData()
|
||||
{
|
||||
$result = $this->queryApi->queryRaw('');
|
||||
|
||||
$this->assertNull($result);
|
||||
}
|
||||
|
||||
public function testQueryEmptyData()
|
||||
{
|
||||
$result = $this->queryApi->query(null);
|
||||
|
||||
$this->assertNull($result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB2Test;
|
||||
|
||||
use GuzzleHttp\Exception\ConnectException;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use InfluxDB2\ApiException;
|
||||
use InfluxDB2\Point;
|
||||
|
||||
require_once('BasicTest.php');
|
||||
/**
|
||||
* Class WriteApiBatchingTest
|
||||
* @package InfluxDB2Test
|
||||
*/
|
||||
class WriteApiBatchingTest extends BasicTest
|
||||
{
|
||||
protected function getWriteOptions(): ?array
|
||||
{
|
||||
return array('writeType' => 2, 'batchSize' => 2);
|
||||
}
|
||||
|
||||
public function testBatchSize()
|
||||
{
|
||||
$this->mockHandler->append(
|
||||
new Response(204),
|
||||
new Response(204)
|
||||
);
|
||||
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek level\\ water_level=1.0 1');
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek level\\ water_level=2.0 2');
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek level\\ water_level=3.0 3');
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek level\\ water_level=4.0 4');
|
||||
|
||||
$this->assertCount(2, $this->requests);
|
||||
|
||||
$result1 = "h2o_feet,location=coyote_creek level\\ water_level=1.0 1\n"
|
||||
. "h2o_feet,location=coyote_creek level\\ water_level=2.0 2";
|
||||
$result2 = "h2o_feet,location=coyote_creek level\\ water_level=3.0 3\n"
|
||||
. "h2o_feet,location=coyote_creek level\\ water_level=4.0 4";
|
||||
|
||||
$this->assertEquals($result1, $this->requests[0]['request']->getBody());
|
||||
$this->assertEquals($result2, $this->requests[1]['request']->getBody());
|
||||
}
|
||||
|
||||
public function testBatchSizeGroupBy()
|
||||
{
|
||||
$this->mockHandler->append(
|
||||
new Response(204),
|
||||
new Response(204),
|
||||
new Response(204),
|
||||
new Response(204),
|
||||
new Response(204)
|
||||
);
|
||||
|
||||
$bucket = 'my-bucket';
|
||||
$bucket2 = 'my-bucket2';
|
||||
|
||||
$this->writeApi->write(
|
||||
'h2o_feet,location=coyote_creek level\\ water_level=1.0 1',
|
||||
'ns',
|
||||
$bucket,
|
||||
'my-org'
|
||||
);
|
||||
$this->writeApi->write(
|
||||
'h2o_feet,location=coyote_creek level\\ water_level=2.0 2',
|
||||
's',
|
||||
$bucket,
|
||||
'my-org'
|
||||
);
|
||||
$this->writeApi->write(
|
||||
'h2o_feet,location=coyote_creek level\\ water_level=3.0 3',
|
||||
'ns',
|
||||
$bucket,
|
||||
'my-org-a'
|
||||
);
|
||||
$this->writeApi->write(
|
||||
'h2o_feet,location=coyote_creek level\\ water_level=4.0 4',
|
||||
'ns',
|
||||
$bucket,
|
||||
'my-org-a'
|
||||
);
|
||||
$this->writeApi->write(
|
||||
'h2o_feet,location=coyote_creek level\\ water_level=5.0 5',
|
||||
'ns',
|
||||
$bucket2,
|
||||
'my-org-a'
|
||||
);
|
||||
$this->writeApi->write(
|
||||
'h2o_feet,location=coyote_creek level\\ water_level=6.0 6',
|
||||
'ns',
|
||||
$bucket,
|
||||
'my-org-a'
|
||||
);
|
||||
|
||||
$this->assertCount(5, $this->requests);
|
||||
|
||||
$request = $this->requests[0]['request'];
|
||||
|
||||
$this->assertEquals(
|
||||
'http://localhost:8086/api/v2/write?org=my-org&bucket=my-bucket&precision=ns',
|
||||
strval($request->getUri())
|
||||
);
|
||||
$this->assertEquals('h2o_feet,location=coyote_creek level\\ water_level=1.0 1', $request->getBody());
|
||||
|
||||
$request = $this->requests[1]['request'];
|
||||
|
||||
$this->assertEquals(
|
||||
'http://localhost:8086/api/v2/write?org=my-org&bucket=my-bucket&precision=s',
|
||||
strval($request->getUri())
|
||||
);
|
||||
$this->assertEquals('h2o_feet,location=coyote_creek level\\ water_level=2.0 2', $request->getBody());
|
||||
|
||||
$request = $this->requests[2]['request'];
|
||||
|
||||
$this->assertEquals(
|
||||
'http://localhost:8086/api/v2/write?org=my-org-a&bucket=my-bucket&precision=ns',
|
||||
strval($request->getUri())
|
||||
);
|
||||
$this->assertEquals("h2o_feet,location=coyote_creek level\\ water_level=3.0 3\n"
|
||||
. 'h2o_feet,location=coyote_creek level\\ water_level=4.0 4', $request->getBody());
|
||||
|
||||
$request = $this->requests[3]['request'];
|
||||
|
||||
$this->assertEquals(
|
||||
'http://localhost:8086/api/v2/write?org=my-org-a&bucket=my-bucket2&precision=ns',
|
||||
strval($request->getUri())
|
||||
);
|
||||
$this->assertEquals('h2o_feet,location=coyote_creek level\\ water_level=5.0 5', $request->getBody());
|
||||
|
||||
$request = $this->requests[4]['request'];
|
||||
|
||||
$this->assertEquals(
|
||||
'http://localhost:8086/api/v2/write?org=my-org-a&bucket=my-bucket&precision=ns',
|
||||
strval($request->getUri())
|
||||
);
|
||||
$this->assertEquals('h2o_feet,location=coyote_creek level\\ water_level=6.0 6', $request->getBody());
|
||||
}
|
||||
|
||||
public function testFlushAllByCloseClient()
|
||||
{
|
||||
$this->mockHandler->append(new Response(204));
|
||||
|
||||
$this->writeApi->writeOptions->batchSize = 10;
|
||||
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek level\\ water_level=1.0 1');
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek level\\ water_level=2.0 2');
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek level\\ water_level=3.0 3');
|
||||
|
||||
$this->assertNull($this->mockHandler->getLastRequest());
|
||||
|
||||
$this->client->close();
|
||||
|
||||
$request = $this->mockHandler->getLastRequest();
|
||||
|
||||
$this->assertEquals(
|
||||
'http://localhost:8086/api/v2/write?org=my-org&bucket=my-bucket&precision=ns',
|
||||
strval($request->getUri())
|
||||
);
|
||||
$this->assertEquals("h2o_feet,location=coyote_creek level\\ water_level=1.0 1\n"
|
||||
. "h2o_feet,location=coyote_creek level\\ water_level=2.0 2\n"
|
||||
. 'h2o_feet,location=coyote_creek level\\ water_level=3.0 3', $request->getBody());
|
||||
}
|
||||
|
||||
public function testRetryIntervalByConfig()
|
||||
{
|
||||
$errorBody = '{"code":"temporarily unavailable","message":"Token is temporarily over quota.'
|
||||
. 'The Retry-After header describes when to try the write again."}';
|
||||
|
||||
$this->mockHandler->append(new Response(
|
||||
429,
|
||||
['X-Platform-Error-Code' => 'temporarily unavailable'],
|
||||
$errorBody
|
||||
), new Response(204));
|
||||
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek water_level=1.0 1');
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek water_level=2.0 2');
|
||||
|
||||
$this->assertCount(2, $this->requests);
|
||||
$request = $this->mockHandler->getLastRequest();
|
||||
|
||||
$this->assertEquals(
|
||||
'http://localhost:8086/api/v2/write?org=my-org&bucket=my-bucket&precision=ns',
|
||||
strval($request->getUri())
|
||||
);
|
||||
$this->assertEquals("h2o_feet,location=coyote_creek water_level=1.0 1\n"
|
||||
. "h2o_feet,location=coyote_creek water_level=2.0 2", $request->getBody()->getContents());
|
||||
}
|
||||
|
||||
public function testRetryIntervalByHeader()
|
||||
{
|
||||
$errorBody = '{"code":"temporarily unavailable","message":"Token is temporarily over quota.'
|
||||
. 'The Retry-After header describes when to try the write again."}';
|
||||
|
||||
$this->mockHandler->append(new Response(
|
||||
429,
|
||||
['X-Platform-Error-Code' => 'temporarily unavailable',
|
||||
'Retry-After' => '3'],
|
||||
$errorBody
|
||||
), new Response(204));
|
||||
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek water_level=1.0 1');
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek water_level=2.0 2');
|
||||
|
||||
$this->assertCount(2, $this->requests);
|
||||
$request = $this->mockHandler->getLastRequest();
|
||||
|
||||
$this->assertEquals(
|
||||
'http://localhost:8086/api/v2/write?org=my-org&bucket=my-bucket&precision=ns',
|
||||
strval($request->getUri())
|
||||
);
|
||||
$this->assertEquals("h2o_feet,location=coyote_creek water_level=1.0 1\n"
|
||||
. "h2o_feet,location=coyote_creek water_level=2.0 2", $request->getBody()->getContents());
|
||||
}
|
||||
|
||||
public function testRetryIntervalMaxRetries()
|
||||
{
|
||||
$errorBody = '{"code":"temporarily unavailable","message":"Token is temporarily over quota.'
|
||||
. 'The Retry-After header describes when to try the write again."}';
|
||||
|
||||
$this->writeApi->writeOptions->maxRetries = 2;
|
||||
|
||||
$this->mockHandler->append(
|
||||
new Response(429, ['X-Platform-Error-Code' => 'temporarily unavailable'], $errorBody),
|
||||
new Response(429, ['X-Platform-Error-Code' => 'temporarily unavailable'], $errorBody),
|
||||
new Response(429, ['X-Platform-Error-Code' => 'temporarily unavailable'], $errorBody)
|
||||
);
|
||||
|
||||
$this->expectException(ApiException::class);
|
||||
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek water_level=1.0 1');
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek water_level=2.0 2');
|
||||
|
||||
$this->assertCount(3, $this->requests);
|
||||
}
|
||||
|
||||
public function testRetryCount()
|
||||
{
|
||||
$this->mockHandler->append(
|
||||
// regular call
|
||||
new Response(429),
|
||||
// retry
|
||||
new Response(429),
|
||||
// retry
|
||||
new Response(429),
|
||||
// retry
|
||||
new Response(429),
|
||||
// not called
|
||||
new Response(429)
|
||||
);
|
||||
|
||||
$this->writeApi->writeOptions->batchSize = 1;
|
||||
$this->writeApi->writeOptions->retryInterval = 1000;
|
||||
$this->writeApi->writeOptions->maxRetries = 3;
|
||||
$this->writeApi->writeOptions->maxRetryDelay = 15000;
|
||||
$this->writeApi->writeOptions->exponentialBase = 2;
|
||||
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2);
|
||||
|
||||
try {
|
||||
$this->writeApi->write($point);
|
||||
} catch (ApiException $e) {
|
||||
$this->assertEquals(429, $e->getCode());
|
||||
}
|
||||
|
||||
$this->assertCount(4, $this->requests);
|
||||
|
||||
$count = $this->mockHandler->count();
|
||||
$this->assertEquals(1, $count);
|
||||
}
|
||||
|
||||
public function testRetryConnectionError()
|
||||
{
|
||||
$errorMessage = 'Failed to connect to localhost port 8086';
|
||||
|
||||
$this->writeApi->writeOptions->maxRetries = 2;
|
||||
$this->writeApi->writeOptions->retryInterval = 1000;
|
||||
$this->writeApi->writeOptions->maxRetryDelay = 15000;
|
||||
$this->writeApi->writeOptions->exponentialBase = 2;
|
||||
|
||||
$this->mockHandler->append(
|
||||
new ConnectException($errorMessage, new Request('POST', '')),
|
||||
new ConnectException($errorMessage, new Request('POST', '')),
|
||||
new ConnectException($errorMessage, new Request('POST', ''))
|
||||
);
|
||||
|
||||
$this->expectException(ApiException::class);
|
||||
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek water_level=1.0 1');
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek water_level=2.0 2');
|
||||
|
||||
$this->assertCount(3, $this->requests);
|
||||
}
|
||||
|
||||
public function testJitterInterval()
|
||||
{
|
||||
$this->mockHandler->append(
|
||||
new Response(204),
|
||||
new Response(204)
|
||||
);
|
||||
|
||||
$this->writeApi->writeOptions->jitterInterval = 2000;
|
||||
|
||||
$start = microtime(true);
|
||||
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek level\\ water_level=1.0 1');
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek level\\ water_level=2.0 2');
|
||||
|
||||
$time = microtime(true) - $start;
|
||||
|
||||
$this->assertTrue($time > 0 && $time <= 2);
|
||||
|
||||
$this->assertCount(1, $this->requests);
|
||||
|
||||
$result1 = "h2o_feet,location=coyote_creek level\\ water_level=1.0 1\n"
|
||||
. "h2o_feet,location=coyote_creek level\\ water_level=2.0 2";
|
||||
|
||||
$this->assertEquals($result1, $this->requests[0]['request']->getBody());
|
||||
}
|
||||
|
||||
public function testRetryContainsMessage()
|
||||
{
|
||||
// create log file
|
||||
fopen("log_test.txt", "w");
|
||||
|
||||
$this->tearDown();
|
||||
$this->setUp("http://localhost:8086", "log_test.txt");
|
||||
|
||||
$this->mockHandler->append(
|
||||
new Response(
|
||||
429,
|
||||
['X-Platform-Error-Code' => 'temporarily unavailable',
|
||||
'Retry-After' => '3'],
|
||||
'org 04014de4ed590000 has exceeded limited_write plan limit'
|
||||
),
|
||||
new Response(204)
|
||||
);
|
||||
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek water_level=1.0 1');
|
||||
$this->writeApi->write('h2o_feet,location=coyote_creek water_level=2.0 2');
|
||||
|
||||
$this->assertCount(2, $this->requests);
|
||||
|
||||
$message = file_get_contents("log_test.txt");
|
||||
$this->assertStringContainsString("The retryable error occurred during writing of data. Reason: 'org 04014de4ed590000 has exceeded limited_write plan limit'. Retry in: 3s.", $message);
|
||||
}
|
||||
}
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB2Test;
|
||||
|
||||
use InfluxDB2\Client;
|
||||
use InfluxDB2\Model\WritePrecision;
|
||||
use InfluxDB2\Point;
|
||||
use InfluxDB2\WriteApi;
|
||||
use InfluxDB2\WriteType;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @group integration
|
||||
*/
|
||||
class WriteApiIntegrationTest extends TestCase
|
||||
{
|
||||
/** @var Client */
|
||||
private $client;
|
||||
/** @var WriteApi */
|
||||
private $writeApi;
|
||||
|
||||
/**
|
||||
* @before
|
||||
*/
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->client = new Client([
|
||||
"url" => "http://localhost:8086",
|
||||
"token" => "my-token",
|
||||
"bucket" => "my-bucket",
|
||||
"precision" => WritePrecision::NS,
|
||||
"org" => "my-org",
|
||||
"debug" => false
|
||||
]);
|
||||
$this->writeApi = $this->client->createWriteApi();
|
||||
}
|
||||
|
||||
public function testExistsWriteApi()
|
||||
{
|
||||
$this->assertNotNull($this->writeApi);
|
||||
}
|
||||
|
||||
public function testWriteApiWriteRaw()
|
||||
{
|
||||
$payload = 'h2o_feet,location=coyote_creek water_level=2.0 2';
|
||||
$response = $this->writeApi->writeRaw($payload);
|
||||
self::assertNull($response);
|
||||
}
|
||||
|
||||
public function testWriteArray()
|
||||
{
|
||||
$data = [
|
||||
'name' => "h2o",
|
||||
'tags' => [
|
||||
'host' => 'aws', 'region' => 'us'
|
||||
],
|
||||
'fields' => [
|
||||
'level' => 5, 'saturation' => 99
|
||||
],
|
||||
'time' => 123
|
||||
];
|
||||
|
||||
$response = $this->writeApi->write($data, WritePrecision::S, "my-bucket", "my-org");
|
||||
self::assertNull($response);
|
||||
}
|
||||
|
||||
public function testBatchingWrite()
|
||||
{
|
||||
$writeApi = $this->client->createWriteApi(
|
||||
["writeType"=>WriteType::BATCHING, 'batchSize'=>3]
|
||||
);
|
||||
|
||||
$data = ['name' => 'cpu',
|
||||
'tags' => ['host' => 'server_nl', 'region' => 'us'],
|
||||
'fields' => ['internal' => 5, 'external' => 6],
|
||||
'time' => microtime(true)];
|
||||
|
||||
$writeApi->write($data, WritePrecision::MS);
|
||||
|
||||
$p1 = ['name' => "h2o", 'tags' => ['host' => 'aws', 'region' => 'us'], 'fields' => ['level' => 1, 'saturation' => 99], 'time' => 1];
|
||||
$p2 = ['name' => "h2o", 'tags' => ['host' => 'aws', 'region' => 'us'], 'fields' => ['level' => 2, 'saturation' => 98], 'time' => 2];
|
||||
$p3 = ['name' => "h2o", 'tags' => ['host' => 'aws', 'region' => 'us'], 'fields' => ['level' => 3, 'saturation' => 97], 'time' => 3];
|
||||
$p4 = ['name' => "h2o", 'tags' => ['host' => 'aws', 'region' => 'us'], 'fields' => ['level' => 4, 'saturation' => 96], 'time' => 4];
|
||||
$p5 = ['name' => "h2o", 'tags' => ['host' => 'aws', 'region' => 'us'], 'fields' => ['level' => 5, 'saturation' => 95], 'time' => 5];
|
||||
$p6 = ['name' => "h2o", 'tags' => ['host' => 'aws', 'region' => 'us'], 'fields' => ['level' => 6, 'saturation' => 95], 'time' => 6];
|
||||
|
||||
$writeApi->write($p1);
|
||||
$writeApi->write($p2);
|
||||
$writeApi->write($p3);
|
||||
$writeApi->write($p4);
|
||||
$writeApi->write($p5);
|
||||
$writeApi->write($p6);
|
||||
|
||||
$this->assertNotNull($writeApi);
|
||||
|
||||
$this->client->close();
|
||||
}
|
||||
|
||||
public function testWriteArrayOfPoint()
|
||||
{
|
||||
$point1 = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2)
|
||||
->time(123);
|
||||
$point2 = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 3)
|
||||
->time(124);
|
||||
|
||||
$data = array($point1, $point2);
|
||||
|
||||
$response = $this->writeApi->write($data, WritePrecision::S, "my-bucket", "my-org");
|
||||
self::assertNull($response);
|
||||
}
|
||||
|
||||
public function testWriteArrayOfArray()
|
||||
{
|
||||
$data1 = [
|
||||
'name' => "h2o",
|
||||
'tags' => [
|
||||
'host' => 'aws', 'region' => 'us'
|
||||
],
|
||||
'fields' => [
|
||||
'level' => 5, 'saturation' => 99
|
||||
],
|
||||
'time' => 123
|
||||
];
|
||||
|
||||
$data2 = [
|
||||
'name' => "h2o",
|
||||
'tags' => [
|
||||
'host' => 'aws', 'region' => 'us'
|
||||
],
|
||||
'fields' => [
|
||||
'level' => 6, 'saturation' => 98
|
||||
],
|
||||
'time' => 124
|
||||
];
|
||||
|
||||
$data = array($data1, $data2);
|
||||
|
||||
$response = $this->writeApi->write($data, WritePrecision::S, "my-bucket", "my-org");
|
||||
self::assertNull($response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,384 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB2Test;
|
||||
|
||||
use Exception;
|
||||
use GuzzleHttp\Exception\ConnectException;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use InfluxDB2\ApiException;
|
||||
use InfluxDB2\Client;
|
||||
use InfluxDB2\Model\WritePrecision;
|
||||
use InfluxDB2\Point;
|
||||
use InfluxDB2\WriteRetry;
|
||||
|
||||
require_once('BasicTest.php');
|
||||
|
||||
/**
|
||||
* Class WriteApiTest
|
||||
* @package InfluxDB2Test
|
||||
*/
|
||||
class WriteApiTest extends BasicTest
|
||||
{
|
||||
private const ID_TAG = "132-987-655";
|
||||
private const CUSTOMER_TAG = "California Miner";
|
||||
|
||||
public function setUp($url = "http://localhost:8086", $logFile = "php://output"): void
|
||||
{
|
||||
parent::setUp($url, $logFile);
|
||||
|
||||
putenv("data_center=LA");
|
||||
}
|
||||
|
||||
public function testWriteLineProtocol()
|
||||
{
|
||||
$this->mockHandler->append(new Response(204));
|
||||
$this->writeApi->write('h2o,location=west value=33i 15');
|
||||
|
||||
$request = $this->mockHandler->getLastRequest();
|
||||
|
||||
$this->assertEquals(
|
||||
'http://localhost:8086/api/v2/write?org=my-org&bucket=my-bucket&precision=ns',
|
||||
strval($request->getUri())
|
||||
);
|
||||
$this->assertEquals('h2o,location=west value=33i 15', $request->getBody());
|
||||
}
|
||||
|
||||
public function testWritePoint()
|
||||
{
|
||||
$this->mockHandler->append(new Response(204));
|
||||
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2);
|
||||
|
||||
$this->writeApi->write($point);
|
||||
|
||||
$request = $this->mockHandler->getLastRequest();
|
||||
|
||||
$this->assertEquals(
|
||||
'http://localhost:8086/api/v2/write?org=my-org&bucket=my-bucket&precision=ns',
|
||||
strval($request->getUri())
|
||||
);
|
||||
$this->assertEquals('h2o,location=europe level=2i', $request->getBody());
|
||||
}
|
||||
|
||||
public function testWriteArray()
|
||||
{
|
||||
$this->mockHandler->append(new Response(204));
|
||||
|
||||
$array = array('name' => 'h2o',
|
||||
'tags' => array('host' => 'aws', 'region' => 'us'),
|
||||
'fields' => array('level' => 5, 'saturation' => '99%'),
|
||||
'time' => 123);
|
||||
|
||||
$this->writeApi->write($array);
|
||||
|
||||
$request = $this->mockHandler->getLastRequest();
|
||||
|
||||
$this->assertEquals(
|
||||
'http://localhost:8086/api/v2/write?org=my-org&bucket=my-bucket&precision=ns',
|
||||
strval($request->getUri())
|
||||
);
|
||||
$this->assertEquals('h2o,host=aws,region=us level=5i,saturation="99%" 123', $request->getBody());
|
||||
}
|
||||
|
||||
public function testWriteCollection()
|
||||
{
|
||||
$this->mockHandler->append(new Response(204));
|
||||
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2);
|
||||
|
||||
$array = array('name' => 'h2o',
|
||||
'tags' => array('host' => 'aws', 'region' => 'us'),
|
||||
'fields' => array('level' => 5, 'saturation' => '99%'),
|
||||
'time' => 123);
|
||||
|
||||
$this->writeApi->write(array('h2o,location=west value=33i 15', null, $point, $array));
|
||||
|
||||
$request = $this->mockHandler->getLastRequest();
|
||||
|
||||
$expected = "h2o,location=west value=33i 15\n"
|
||||
. "h2o,location=europe level=2i\n"
|
||||
. "h2o,host=aws,region=us level=5i,saturation=\"99%\" 123";
|
||||
|
||||
$this->assertEquals(
|
||||
'http://localhost:8086/api/v2/write?org=my-org&bucket=my-bucket&precision=ns',
|
||||
strval($request->getUri())
|
||||
);
|
||||
$this->assertEquals($expected, strval($request->getBody()));
|
||||
}
|
||||
|
||||
public function testAuthorizationHeader()
|
||||
{
|
||||
$this->mockHandler->append(new Response(204));
|
||||
$this->writeApi->write('h2o,location=west value=33i 15');
|
||||
|
||||
$request = $this->mockHandler->getLastRequest();
|
||||
|
||||
$this->assertEquals(
|
||||
'http://localhost:8086/api/v2/write?org=my-org&bucket=my-bucket&precision=ns',
|
||||
strval($request->getUri())
|
||||
);
|
||||
$this->assertEquals('Token my-token', implode(' ', $request->getHeaders()['Authorization']));
|
||||
}
|
||||
|
||||
public function testWithoutData()
|
||||
{
|
||||
$this->mockHandler->append(new Response(204));
|
||||
$this->writeApi->write('');
|
||||
|
||||
$request = $this->mockHandler->getLastRequest();
|
||||
|
||||
$this->assertNull($request);
|
||||
}
|
||||
|
||||
public function testInfluxException()
|
||||
{
|
||||
$errorBody = '{"code":"invalid","message":"unable to parse \'h2o_feet, location=coyote_creek water_level=1.0 1\': missing tag key"}';
|
||||
|
||||
$this->mockHandler->append(new Response(400, array('X-Platform-Error-Code' => 'invalid'), $errorBody));
|
||||
|
||||
try {
|
||||
$this->writeApi->write('h2o,location=west value=33i 15');
|
||||
$this->fail();
|
||||
} catch (ApiException $e) {
|
||||
$this->assertEquals(400, $e->getCode());
|
||||
$this->assertEquals('invalid', implode($e->getResponseHeaders()['X-Platform-Error-Code']));
|
||||
$this->assertEquals($errorBody, strval($e->getResponseBody()));
|
||||
} catch (Exception $e) {
|
||||
$this->fail();
|
||||
}
|
||||
}
|
||||
|
||||
public function testWritePointWithDefaultTags()
|
||||
{
|
||||
$this->mockHandler->append(new Response(204));
|
||||
|
||||
$this->writeApi->pointSettings->addDefaultTag('id', WriteApiTest::ID_TAG);
|
||||
$this->writeApi->pointSettings->addDefaultTag('customer', WriteApiTest::CUSTOMER_TAG);
|
||||
$this->writeApi->pointSettings->addDefaultTag('data_center', '${env.data_center}');
|
||||
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2);
|
||||
|
||||
$this->writeApi->write($point);
|
||||
|
||||
$request = $this->mockHandler->getLastRequest();
|
||||
|
||||
$this->assertEquals(
|
||||
'http://localhost:8086/api/v2/write?org=my-org&bucket=my-bucket&precision=ns',
|
||||
strval($request->getUri())
|
||||
);
|
||||
$this->assertEquals(
|
||||
'h2o,customer=California\ Miner,data_center=LA,id=132-987-655,location=europe level=2i',
|
||||
strval($request->getBody())
|
||||
);
|
||||
}
|
||||
|
||||
public function testWriteArrayWithDefaultTags()
|
||||
{
|
||||
$this->mockHandler->append(new Response(204));
|
||||
|
||||
$this->writeApi->pointSettings->addDefaultTag('id', WriteApiTest::ID_TAG);
|
||||
$this->writeApi->pointSettings->addDefaultTag('customer', WriteApiTest::CUSTOMER_TAG);
|
||||
$this->writeApi->pointSettings->addDefaultTag('data_center', '${env.data_center}');
|
||||
|
||||
$array = array('name' => 'h2o',
|
||||
'tags' => array('host' => 'aws', 'region' => 'us'),
|
||||
'fields' => array('level' => 5, 'saturation' => '99%'),
|
||||
'time' => 123);
|
||||
|
||||
$this->writeApi->write($array);
|
||||
|
||||
$request = $this->mockHandler->getLastRequest();
|
||||
|
||||
$this->assertEquals(
|
||||
'http://localhost:8086/api/v2/write?org=my-org&bucket=my-bucket&precision=ns',
|
||||
strval($request->getUri())
|
||||
);
|
||||
$this->assertEquals(
|
||||
'h2o,customer=California\ Miner,data_center=LA,host=aws,id=132-987-655,region=us level=5i,saturation="99%" 123',
|
||||
strval($request->getBody())
|
||||
);
|
||||
}
|
||||
|
||||
public function testWriteCollectionWithDefaultTags()
|
||||
{
|
||||
$this->mockHandler->append(new Response(204));
|
||||
|
||||
$this->writeApi->pointSettings->addDefaultTag('id', WriteApiTest::ID_TAG);
|
||||
$this->writeApi->pointSettings->addDefaultTag('customer', WriteApiTest::CUSTOMER_TAG);
|
||||
$this->writeApi->pointSettings->addDefaultTag('data_center', '${env.data_center}');
|
||||
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2);
|
||||
|
||||
$array = array('name' => 'h2o',
|
||||
'tags' => array('host' => 'aws', 'region' => 'us'),
|
||||
'fields' => array('level' => 5, 'saturation' => '99%'),
|
||||
'time' => 123);
|
||||
|
||||
$this->writeApi->write(array('h2o,location=west value=33i 15', null, $point, $array));
|
||||
|
||||
$request = $this->mockHandler->getLastRequest();
|
||||
|
||||
$expected = "h2o,location=west value=33i 15\n"
|
||||
. "h2o,customer=California\ Miner,data_center=LA,id=132-987-655,location=europe level=2i\n"
|
||||
. "h2o,customer=California\ Miner,data_center=LA,host=aws,id=132-987-655,region=us level=5i,saturation=\"99%\" 123";
|
||||
|
||||
$this->assertEquals(
|
||||
'http://localhost:8086/api/v2/write?org=my-org&bucket=my-bucket&precision=ns',
|
||||
strval($request->getUri())
|
||||
);
|
||||
$this->assertEquals($expected, strval($request->getBody()));
|
||||
}
|
||||
|
||||
public function testWriteArrayWithoutTagsWithDefaultTags()
|
||||
{
|
||||
$this->mockHandler->append(new Response(204));
|
||||
|
||||
$this->writeApi->pointSettings->addDefaultTag('id', WriteApiTest::ID_TAG);
|
||||
$this->writeApi->pointSettings->addDefaultTag('customer', WriteApiTest::CUSTOMER_TAG);
|
||||
$this->writeApi->pointSettings->addDefaultTag('data_center', '${env.data_center}');
|
||||
|
||||
$array = array('name' => 'h2o',
|
||||
'fields' => array('level' => 5, 'saturation' => '99%'),
|
||||
'time' => 123);
|
||||
|
||||
$this->writeApi->write($array);
|
||||
|
||||
$request = $this->mockHandler->getLastRequest();
|
||||
|
||||
$this->assertEquals(
|
||||
'http://localhost:8086/api/v2/write?org=my-org&bucket=my-bucket&precision=ns',
|
||||
strval($request->getUri())
|
||||
);
|
||||
$this->assertEquals(
|
||||
'h2o,customer=California\ Miner,data_center=LA,id=132-987-655 level=5i,saturation="99%" 123',
|
||||
strval($request->getBody())
|
||||
);
|
||||
}
|
||||
|
||||
public function testRetryCount()
|
||||
{
|
||||
$this->mockHandler->append(
|
||||
// regular call
|
||||
new Response(429),
|
||||
// retry
|
||||
new Response(429),
|
||||
// retry
|
||||
new Response(429),
|
||||
// retry
|
||||
new Response(429),
|
||||
// not called
|
||||
new Response(429)
|
||||
);
|
||||
|
||||
$this->writeApi->writeOptions->retryInterval = 1000;
|
||||
$this->writeApi->writeOptions->maxRetries = 3;
|
||||
$this->writeApi->writeOptions->maxRetryDelay = 15000;
|
||||
$this->writeApi->writeOptions->exponentialBase = 2;
|
||||
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2);
|
||||
|
||||
$this->expectExceptionCode(429);
|
||||
$this->expectException(ApiException::class);
|
||||
$this->writeApi->write($point);
|
||||
|
||||
$this->assertCount(4, $this->requests);
|
||||
$this->assertCount(1, $this->mockHandler);
|
||||
}
|
||||
|
||||
public function testRetryMaxTime()
|
||||
{
|
||||
$this->mockHandler->append(
|
||||
// regular call
|
||||
new Response(429),
|
||||
// retry
|
||||
new Response(429),
|
||||
// retry
|
||||
new Response(200)
|
||||
);
|
||||
|
||||
$this->writeApi->writeOptions->retryInterval = 1000;
|
||||
$this->writeApi->writeOptions->maxRetries = 3;
|
||||
$this->writeApi->writeOptions->maxRetryDelay = 15000;
|
||||
$this->writeApi->writeOptions->exponentialBase = 2;
|
||||
$this->writeApi->writeOptions->maxRetryTime = 300;
|
||||
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2);
|
||||
|
||||
$this->expectException(ApiException::class);
|
||||
$this->expectExceptionCode(429);
|
||||
|
||||
$this->writeApi->write($point);
|
||||
|
||||
$this->assertCount(2, $this->requests);
|
||||
$this->assertCount(1, $this->mockHandler);
|
||||
}
|
||||
|
||||
|
||||
public function testRetryBackoffTime()
|
||||
{
|
||||
$retry = new WriteRetry();
|
||||
|
||||
$backoff = $retry->getBackoffTime(1);
|
||||
$this->assertGreaterThanOrEqual(5000, $backoff);
|
||||
$this->assertLessThanOrEqual(10000, $backoff);
|
||||
|
||||
$backoff = $retry->getBackoffTime(2);
|
||||
$this->assertGreaterThanOrEqual(10000, $backoff);
|
||||
$this->assertLessThanOrEqual(20000, $backoff);
|
||||
|
||||
$backoff = $retry->getBackoffTime(3);
|
||||
$this->assertGreaterThanOrEqual(20000, $backoff);
|
||||
$this->assertLessThanOrEqual(40000, $backoff);
|
||||
|
||||
$backoff = $retry->getBackoffTime(4);
|
||||
$this->assertGreaterThanOrEqual(40000, $backoff);
|
||||
$this->assertLessThanOrEqual(80000, $backoff);
|
||||
|
||||
$backoff = $retry->getBackoffTime(5);
|
||||
$this->assertGreaterThanOrEqual(80000, $backoff);
|
||||
$this->assertLessThanOrEqual(125000, $backoff);
|
||||
|
||||
$backoff = $retry->getBackoffTime(6);
|
||||
$this->assertGreaterThanOrEqual(80000, $backoff);
|
||||
$this->assertLessThanOrEqual(125000, $backoff);
|
||||
}
|
||||
|
||||
public function testConnectExceptionRetry()
|
||||
{
|
||||
$client = new Client([
|
||||
"url" => "http://nonexistenthost:8086/",
|
||||
"token" => "my-token",
|
||||
"bucket" => "my-bucket",
|
||||
"precision" => WritePrecision::NS,
|
||||
"org" => "my-org",
|
||||
"logFile" => "php://output"
|
||||
]);
|
||||
|
||||
$writeApi = $client->createWriteApi(["retryInterval" => 100]);
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2);
|
||||
|
||||
$this->expectException(ApiException::class);
|
||||
$this->expectExceptionMessage("Could not resolve host: nonexistenthost");
|
||||
|
||||
try {
|
||||
$writeApi->write($point);
|
||||
} catch (ApiException $e) {
|
||||
$this->assertEquals(ConnectException::class, get_class($e->getPrevious()));
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace InfluxDB2Test;
|
||||
|
||||
use InfluxDB2\Client;
|
||||
use InfluxDB2\Model\WritePrecision;
|
||||
use InfluxDB2\Point;
|
||||
use InfluxDB2\UdpWriter;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Class WriteUdpTest
|
||||
* @package InfluxDB2Test
|
||||
*/
|
||||
class WriteUdpTest extends TestCase
|
||||
{
|
||||
protected $baseConfig = [
|
||||
"url" => "http://localhost:8086",
|
||||
"token" => "my-token",
|
||||
"bucket" => "my-bucket",
|
||||
"precision" => WritePrecision::NS,
|
||||
"org" => "my-org",
|
||||
"logFile" => "php://output",
|
||||
];
|
||||
|
||||
protected function getWriterMock()
|
||||
{
|
||||
$method = new \ReflectionMethod(UdpWriter::class, 'writeSocket');
|
||||
$method->setAccessible(true);
|
||||
return $this->getMockBuilder(UdpWriter::class)
|
||||
->setMethods(['writeSocket'])
|
||||
->setConstructorArgs([$this->baseConfig + ['udpPort' => 1000]])
|
||||
->getMock();
|
||||
}
|
||||
|
||||
public function testRequireOptions()
|
||||
{
|
||||
$client = new Client($this->baseConfig);
|
||||
$this->expectException(\Exception::class);
|
||||
$client->createUdpWriter();
|
||||
}
|
||||
|
||||
public function testValidOptions()
|
||||
{
|
||||
$this->expectNotToPerformAssertions();
|
||||
$client = new Client($this->baseConfig + ['udpPort' => 1000]);
|
||||
$client->createUdpWriter();
|
||||
}
|
||||
|
||||
public function testSocketError()
|
||||
{
|
||||
$writer = $this->getWriterMock();
|
||||
$writer->method('writeSocket')->willReturn(false);
|
||||
$this->expectException(\Exception::class);
|
||||
$writer->write('h2o,location=west value=33i 15');
|
||||
}
|
||||
|
||||
public function testLineProtocol()
|
||||
{
|
||||
$writer = $this->getWriterMock();
|
||||
$buffer = '';
|
||||
$writer->method('writeSocket')->willReturnCallback(function ($data) use (&$buffer) {
|
||||
$buffer = $data;
|
||||
});
|
||||
$writer->write('h2o,location=west value=33i 15');
|
||||
$this->assertEquals('h2o,location=west value=33i 15', $buffer);
|
||||
}
|
||||
|
||||
public function testWriteArray()
|
||||
{
|
||||
$array = [
|
||||
'name' => 'h2o',
|
||||
'tags' => ['host' => 'aws', 'region' => 'us'],
|
||||
'fields' => ['level' => 5, 'saturation' => '99%'],
|
||||
'time' => 123
|
||||
];
|
||||
|
||||
$writer = $this->getWriterMock();
|
||||
$buffer = '';
|
||||
$writer->method('writeSocket')->willReturnCallback(function ($data) use (&$buffer) {
|
||||
$buffer = $data;
|
||||
});
|
||||
$writer->write($array);
|
||||
$this->assertEquals('h2o,host=aws,region=us level=5i,saturation="99%" 123', $buffer);
|
||||
}
|
||||
|
||||
public function testWriteCollection()
|
||||
{
|
||||
$point = Point::measurement('h2o')
|
||||
->addTag('location', 'europe')
|
||||
->addField('level', 2);
|
||||
|
||||
$array = [
|
||||
'name' => 'h2o',
|
||||
'tags' => ['host' => 'aws', 'region' => 'us'],
|
||||
'fields' => ['level' => 5, 'saturation' => '99%'],
|
||||
'time' => 123
|
||||
];
|
||||
|
||||
$writer = $this->getWriterMock();
|
||||
$buffer = '';
|
||||
$writer->method('writeSocket')->willReturnCallback(function ($data) use (&$buffer) {
|
||||
$buffer = $data;
|
||||
});
|
||||
$writer->write(['h2o,location=west value=33i 15', null, $point, $array]);
|
||||
$expected = "h2o,location=west value=33i 15\n"
|
||||
. "h2o,location=europe level=2i\n"
|
||||
. "h2o,host=aws,region=us level=5i,saturation=\"99%\" 123";
|
||||
$this->assertEquals($expected, $buffer);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user