Skip to content

Commit 193d995

Browse files
committed
Added letter time notation support to Util::parseValue();
Added a preliminary changelog; Altered the Packer template to support newer RouterOS versions; Moved some Communicator tests into a new test folder.
1 parent 56fa48c commit 193d995

22 files changed

+636
-160
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Project: [![Total Downloads](https://poser.pugx.org/pear2/net_routeros/downloads)](https://packagist.org/packages/pear2/net_routeros) [![License](https://poser.pugx.org/pear2/net_routeros/license)](https://packagist.org/packages/pear2/net_routeros)
22

3-
Stable: [![Dependency Status](https://www.versioneye.com/php/pear2:net_routeros/dev-master/badge.svg)](https://www.versioneye.com/php/pear2:net_routeros/dev-master)
3+
Stable (master): [![Dependency Status](https://www.versioneye.com/php/pear2:net_routeros/dev-master/badge.svg)](https://www.versioneye.com/php/pear2:net_routeros/dev-master)
44

5-
Unstable: [![Dependency Status](https://www.versioneye.com/php/pear2:net_routeros/dev-develop/badge.svg)](https://www.versioneye.com/php/pear2:net_routeros/dev-develop)
5+
Unstable (develop): [![Dependency Status](https://www.versioneye.com/php/pear2:net_routeros/dev-develop/badge.svg)](https://www.versioneye.com/php/pear2:net_routeros/dev-develop)
66
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/pear2/Net_RouterOS/badges/quality-score.png?b=develop)](https://scrutinizer-ci.com/g/pear2/Net_RouterOS/?branch=develop)
77

88
See [the project wiki](https://github.com/pear2/Net_RouterOS/wiki) for installation instructions and other documentation.

RELEASE-1.0.0b6

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Bug fixes, mostly.
2+
3+
* New Util methods:
4+
- newRequest()
5+
- comment()
6+
* Util::parseValue() now supports letter notation for time (1h2m3s), not just double colon notation (01:02:03), modeled after RouterOS. Related to that is also that leading zeroes, and zero minutes and seconds are now optional (e.g. "1:" is a valid way of saying 1 hour). Sub-second information is rounded up to the nearest second on current PHP versions (future versions are expected to support sub-second information in DateInterval by allowing seconds to be a double; The code currently attempts to give DateInterval a double, falling back to rounding to a second).
7+
* Client::login() consumes the !done or !fatal response even when called on an already logged in connection.

src/PEAR2/Net/RouterOS/Util.php

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,15 @@
3636
use Countable;
3737

3838
/**
39-
* Used to reliably write to streams at {@link static::prepareScript()}.
39+
* Used to reliably write to streams at {@link Util::prepareScript()}.
4040
*/
4141
use PEAR2\Net\Transmitter\Stream;
4242

43+
/**
44+
* Used to catch a DateInterval exception at {@link Util::parseValue()}.
45+
*/
46+
use Exception as E;
47+
4348
/**
4449
* Utility class.
4550
*
@@ -108,11 +113,19 @@ public static function parseValue($value)
108113
return $num;
109114
} elseif (preg_match(
110115
'/^
111-
(?:(\d+)w)?
112-
(?:(\d+)d)?
113-
(?:(\d\d)\:)?
114-
(\d\d)\:
115-
(\d\d(:\.\d{1,6})?)
116+
(?:(\d+)w)?
117+
(?:(\d+)d)?
118+
(?:(\d+)(?:\:|h))?
119+
(?|
120+
(\d+)\:
121+
(\d*(?:\.\d{1,9})?)
122+
|
123+
(?:(\d+)m)?
124+
(?:(\d+|\d*\.\d{1,9})s)?
125+
(?:((?5))ms)?
126+
(?:((?5))us)?
127+
(?:((?5))ns)?
128+
)
116129
$/x',
117130
$value,
118131
$time
@@ -121,12 +134,55 @@ public static function parseValue($value)
121134
if (isset($time[1])) {
122135
$days += 7 * (int)$time[1];
123136
}
124-
if ('' === $time[3]) {
137+
if (empty($time[3])) {
125138
$time[3] = 0;
126139
}
127-
return new DateInterval(
128-
"P{$days}DT{$time[3]}H{$time[4]}M{$time[5]}S"
129-
);
140+
if (empty($time[4])) {
141+
$time[4] = 0;
142+
}
143+
if (empty($time[5])) {
144+
$time[5] = 0;
145+
}
146+
147+
$subsecondTime = 0.0;
148+
//@codeCoverageIgnoreStart
149+
// No PHP version currently supports sub-second DateIntervals,
150+
// meaning this section is untestable, since no version constraints
151+
// can be specified for test inputs.
152+
// All inputs currently use integer seconds only, making this
153+
// section unreachable during tests.
154+
// Nevertheless, this section exists right now, in order to provide
155+
// such support as soon as PHP has it.
156+
if (!empty($time[6])) {
157+
$subsecondTime += ((double)$time[6]) / 1000;
158+
}
159+
if (!empty($time[7])) {
160+
$subsecondTime += ((double)$time[7]) / 1000000;
161+
}
162+
if (!empty($time[8])) {
163+
$subsecondTime += ((double)$time[8]) / 1000000000;
164+
}
165+
//@codeCoverageIgnoreEnd
166+
167+
$secondsSpec = $time[5] + $subsecondTime;
168+
try {
169+
return new DateInterval(
170+
"P{$days}DT{$time[3]}H{$time[4]}M{$secondsSpec}S"
171+
);
172+
//@codeCoverageIgnoreStart
173+
// See previous ignored section's note.
174+
//
175+
// This section is added for backwards compatibility with current
176+
// PHP versions, when in the future sub-second support is added.
177+
// In that event, the test inputs for older versions will be
178+
// expected to get a rounded up result of the sub-second data.
179+
} catch (E $e) {
180+
$secondsSpec = (int)round($secondsSpec);
181+
return new DateInterval(
182+
"P{$days}DT{$time[3]}H{$time[4]}M{$secondsSpec}S"
183+
);
184+
}
185+
//@codeCoverageIgnoreEnd
130186
} elseif (('"' === $value[0]) && substr(strrev($value), 0, 1) === '"') {
131187
return str_replace(
132188
array('\"', '\\\\', "\\\n", "\\\r\n", "\\\r"),

tests/Communicator/Safe.php

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
3+
namespace PEAR2\Net\RouterOS\Test\Communicator;
4+
5+
use PEAR2\Net\RouterOS\Communicator;
6+
use PEAR2\Net\RouterOS\Request;
7+
use PEAR2\Net\RouterOS\Response;
8+
use PEAR2\Net\RouterOS\Query;
9+
use PEAR2\Net\RouterOS\InvalidArgumentException;
10+
use PEAR2\Net\RouterOS\SocketException;
11+
use PHPUnit_Framework_TestCase;
12+
13+
abstract class Safe extends PHPUnit_Framework_TestCase
14+
{
15+
16+
/**
17+
* @var Communicator
18+
*/
19+
protected $object;
20+
21+
public function testNonSeekableCommunicatorWord()
22+
{
23+
$value = fopen('php://output', 'a');
24+
try {
25+
$this->object->sendWordFromStream('', $value);
26+
$this->fail('Call had to fail.');
27+
} catch (InvalidArgumentException $e) {
28+
$this->assertEquals(
29+
InvalidArgumentException::CODE_SEEKABLE_REQUIRED,
30+
$e->getCode(),
31+
'Improper exception code.'
32+
);
33+
}
34+
}
35+
36+
public function testInvokability()
37+
{
38+
$com = $this->object;
39+
$request = new Request('/ping');
40+
$request('address', HOSTNAME)->setTag('p');
41+
$this->assertEquals(HOSTNAME, $request('address'));
42+
$this->assertEquals('p', $request->getTag());
43+
$this->assertEquals('p', $request());
44+
$request($com);
45+
$response = new Response(
46+
$com,
47+
false,
48+
ini_get('default_socket_timeout')
49+
);
50+
$this->assertInternalType('string', $response());
51+
$this->assertEquals(HOSTNAME, $response('host'));
52+
53+
$request = new Request('/queue/simple/print');
54+
$query = Query::where('target', HOSTNAME_INVALID . '/32');
55+
$request($query);
56+
$this->assertSame($query, $request->getQuery());
57+
$com('/log/print');
58+
$com('');
59+
}
60+
61+
public function testInvalidSocketOnReceive()
62+
{
63+
try {
64+
new Response($this->object);
65+
$this->fail('Receiving had to fail.');
66+
} catch (SocketException $e) {
67+
$this->assertEquals(
68+
SocketException::CODE_NO_DATA,
69+
$e->getCode(),
70+
'Improper exception code.'
71+
);
72+
}
73+
}
74+
75+
public function testInvalidSocketOnStreamReceive()
76+
{
77+
try {
78+
$response = new Response($this->object, true);
79+
$this->fail('Receiving had to fail.');
80+
} catch (SocketException $e) {
81+
$this->assertEquals(
82+
SocketException::CODE_NO_DATA,
83+
$e->getCode(),
84+
'Improper exception code.'
85+
);
86+
}
87+
}
88+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace PEAR2\Net\RouterOS\Test\Communicator\Safe;
4+
5+
use PEAR2\Net\RouterOS\Test\Communicator\Safe;
6+
7+
require_once __DIR__ . '/../Safe.php';
8+
9+
abstract class NonPersistent extends Safe
10+
{
11+
protected function tearDown()
12+
{
13+
unset($this->object);
14+
}
15+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace PEAR2\Net\RouterOS\Test\Communicator\Safe\NonPersistent;
4+
5+
use PEAR2\Net\RouterOS\Client;
6+
use PEAR2\Net\RouterOS\Communicator;
7+
use PEAR2\Net\RouterOS\Test\Communicator\Safe\NonPersistent;
8+
use PEAR2\Net\Transmitter\NetworkStream;
9+
10+
require_once __DIR__ . '/../NonPersistent.php';
11+
12+
/**
13+
* ~
14+
*
15+
* @group Communicator
16+
* @group Safe
17+
* @group NonPersistent
18+
* @group Encrypted
19+
*
20+
* @requires extension openssl
21+
*
22+
* @category Net
23+
* @package PEAR2_Net_RouterOS
24+
* @author Vasil Rangelov <[email protected]>
25+
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
26+
* @link http://pear2.php.net/PEAR2_Net_RouterOS
27+
*/
28+
class EncryptedTest extends NonPersistent
29+
{
30+
protected function setUp()
31+
{
32+
$this->object = new Communicator(
33+
\HOSTNAME,
34+
ENC_PORT,
35+
false,
36+
null,
37+
NetworkStream::CRYPTO_TLS
38+
);
39+
Client::login($this->object, USERNAME, PASSWORD);
40+
}
41+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace PEAR2\Net\RouterOS\Test\Communicator\Safe\NonPersistent;
4+
5+
use PEAR2\Net\RouterOS\Client;
6+
use PEAR2\Net\RouterOS\Communicator;
7+
use PEAR2\Net\RouterOS\Test\Communicator\Safe\NonPersistent;
8+
9+
require_once __DIR__ . '/../NonPersistent.php';
10+
11+
/**
12+
* ~
13+
*
14+
* @group Communicator
15+
* @group Safe
16+
* @group NonPersistent
17+
* @group Unencrypted
18+
*
19+
* @category Net
20+
* @package PEAR2_Net_RouterOS
21+
* @author Vasil Rangelov <[email protected]>
22+
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
23+
* @link http://pear2.php.net/PEAR2_Net_RouterOS
24+
*/
25+
class UnencryptedTest extends NonPersistent
26+
{
27+
protected function setUp()
28+
{
29+
$this->object = new Communicator(\HOSTNAME, PORT);
30+
Client::login($this->object, USERNAME, PASSWORD);
31+
}
32+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace PEAR2\Net\RouterOS\Test\Communicator\Safe;
4+
5+
use PEAR2\Net\RouterOS\Test\Communicator\Safe;
6+
7+
require_once __DIR__ . '/../Safe.php';
8+
9+
abstract class Persistent extends Safe
10+
{
11+
12+
protected function tearDown()
13+
{
14+
$this->object->close();
15+
unset($this->object);
16+
}
17+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace PEAR2\Net\RouterOS\Test\Communicator\Safe\Persistent;
4+
5+
use PEAR2\Net\RouterOS\Client;
6+
use PEAR2\Net\RouterOS\Communicator;
7+
use PEAR2\Net\RouterOS\Test\Communicator\Safe\Persistent;
8+
use PEAR2\Net\Transmitter\NetworkStream;
9+
10+
require_once __DIR__ . '/../Persistent.php';
11+
12+
/**
13+
* ~
14+
*
15+
* @group Communicator
16+
* @group Safe
17+
* @group Persistent
18+
* @group Encrypted
19+
*
20+
* @requires extension openssl
21+
* @requires PHP 5.3.9
22+
*
23+
* @category Net
24+
* @package PEAR2_Net_RouterOS
25+
* @author Vasil Rangelov <[email protected]>
26+
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
27+
* @link http://pear2.php.net/PEAR2_Net_RouterOS
28+
*/
29+
class EncryptedTest extends Persistent
30+
{
31+
protected function setUp()
32+
{
33+
$this->object = new Communicator(
34+
\HOSTNAME,
35+
ENC_PORT,
36+
true,
37+
null,
38+
NetworkStream::CRYPTO_TLS
39+
);
40+
Client::login($this->object, USERNAME, PASSWORD);
41+
}
42+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace PEAR2\Net\RouterOS\Test\Communicator\Safe\Persistent;
4+
5+
use PEAR2\Net\RouterOS\Client;
6+
use PEAR2\Net\RouterOS\Communicator;
7+
use PEAR2\Net\RouterOS\Test\Communicator\Safe\Persistent;
8+
9+
require_once __DIR__ . '/../Persistent.php';
10+
11+
/**
12+
* ~
13+
*
14+
* @group Communicator
15+
* @group Safe
16+
* @group Persistent
17+
* @group Unencrypted
18+
*
19+
* @requires PHP 5.3.9
20+
*
21+
* @category Net
22+
* @package PEAR2_Net_RouterOS
23+
* @author Vasil Rangelov <[email protected]>
24+
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
25+
* @link http://pear2.php.net/PEAR2_Net_RouterOS
26+
*/
27+
class UnencryptedTest extends Persistent
28+
{
29+
protected function setUp()
30+
{
31+
$this->object = new Communicator(\HOSTNAME, PORT, true);
32+
Client::login($this->object, USERNAME, PASSWORD);
33+
}
34+
}

0 commit comments

Comments
 (0)