Skip to content

Commit a49c733

Browse files
committed
Move tests to each component
1 parent 8c5ccc3 commit a49c733

12 files changed

Lines changed: 1479 additions & 0 deletions
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
namespace React\Test\Dns\Config;
4+
5+
use React\Dns\Config\FilesystemFactory;
6+
7+
class FilesystemFactoryTest extends \PHPUnit_Framework_TestCase
8+
{
9+
/** @test */
10+
public function parseEtcResolvConfShouldParseCorrectly()
11+
{
12+
$contents = '#
13+
# Mac OS X Notice
14+
#
15+
# This file is not used by the host name and address resolution
16+
# or the DNS query routing mechanisms used by most processes on
17+
# this Mac OS X system.
18+
#
19+
# This file is automatically generated.
20+
#
21+
domain v.cablecom.net
22+
nameserver 127.0.0.1
23+
nameserver 8.8.8.8
24+
';
25+
$expected = array('127.0.0.1', '8.8.8.8');
26+
27+
$capturedConfig = null;
28+
29+
$loop = $this->getMock('React\EventLoop\LoopInterface');
30+
$factory = new FilesystemFactory($loop);
31+
$factory->parseEtcResolvConf($contents)->then(function ($config) use (&$capturedConfig) {
32+
$capturedConfig = $config;
33+
});
34+
35+
$this->assertNotNull($capturedConfig);
36+
$this->assertSame($expected, $capturedConfig->nameservers);
37+
}
38+
39+
/** @test */
40+
public function createShouldLoadStuffFromFilesystem()
41+
{
42+
$expected = array('8.8.8.8');
43+
44+
$triggerListener = null;
45+
$capturedConfig = null;
46+
47+
$loop = $this->getMock('React\EventLoop\LoopInterface');
48+
$loop
49+
->expects($this->once())
50+
->method('addReadStream')
51+
->will($this->returnCallback(function ($stream, $listener) use (&$triggerListener) {
52+
$triggerListener = function () use ($stream, $listener) {
53+
call_user_func($listener, $stream);
54+
};
55+
}));
56+
57+
$factory = new FilesystemFactory($loop);
58+
$factory->create(__DIR__.'/../Fixtures/etc/resolv.conf')->then(function ($config) use (&$capturedConfig) {
59+
$capturedConfig = $config;
60+
});
61+
62+
$triggerListener();
63+
64+
$this->assertNotNull($capturedConfig);
65+
$this->assertSame($expected, $capturedConfig->nameservers);
66+
}
67+
}

tests/Fixtures/etc/resolv.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
nameserver 8.8.8.8
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace React\Tests\Dns\Protocol;
4+
5+
use React\Dns\Protocol\BinaryDumper;
6+
use React\Dns\Model\Message;
7+
8+
class BinaryDumperTest extends \PHPUnit_Framework_TestCase
9+
{
10+
public function testRequestToBinary()
11+
{
12+
$data = "";
13+
$data .= "72 62 01 00 00 01 00 00 00 00 00 00"; // header
14+
$data .= "04 69 67 6f 72 02 69 6f 00"; // question: igor.io
15+
$data .= "00 01 00 01"; // question: type A, class IN
16+
17+
$expected = $this->formatHexDump(str_replace(' ', '', $data), 2);
18+
19+
$request = new Message();
20+
$request->header->set('id', 0x7262);
21+
$request->header->set('rd', 1);
22+
23+
$request->questions[] = array(
24+
'name' => 'igor.io',
25+
'type' => Message::TYPE_A,
26+
'class' => Message::CLASS_IN,
27+
);
28+
29+
$request->prepare();
30+
31+
$dumper = new BinaryDumper();
32+
$data = $dumper->toBinary($request);
33+
$data = $this->convertBinaryToHexDump($data);
34+
35+
$this->assertSame($expected, $data);
36+
}
37+
38+
private function convertBinaryToHexDump($input)
39+
{
40+
return $this->formatHexDump(implode('', unpack('H*', $input)));
41+
}
42+
43+
private function formatHexDump($input)
44+
{
45+
return implode(' ', str_split($input, 2));
46+
}
47+
}

tests/Protocol/ParserTest.php

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
<?php
2+
3+
namespace React\Tests\Dns\Protocol;
4+
5+
use React\Dns\Protocol\Parser;
6+
use React\Dns\Model\Message;
7+
8+
class ParserTest extends \PHPUnit_Framework_TestCase
9+
{
10+
/**
11+
* @dataProvider provideConvertTcpDumpToBinary
12+
*/
13+
public function testConvertTcpDumpToBinary($expected, $data)
14+
{
15+
$this->assertSame($expected, $this->convertTcpDumpToBinary($data));
16+
}
17+
18+
public function provideConvertTcpDumpToBinary()
19+
{
20+
return array(
21+
array(chr(0x72).chr(0x62), "72 62"),
22+
array(chr(0x72).chr(0x62).chr(0x01).chr(0x00), "72 62 01 00"),
23+
array(chr(0x72).chr(0x62).chr(0x01).chr(0x00).chr(0x00).chr(0x01), "72 62 01 00 00 01"),
24+
array(chr(0x01).chr(0x00).chr(0x01), "01 00 01"),
25+
);
26+
}
27+
28+
public function testParseRequest()
29+
{
30+
$data = "";
31+
$data .= "72 62 01 00 00 01 00 00 00 00 00 00"; // header
32+
$data .= "04 69 67 6f 72 02 69 6f 00"; // question: igor.io
33+
$data .= "00 01 00 01"; // question: type A, class IN
34+
35+
$data = $this->convertTcpDumpToBinary($data);
36+
37+
$request = new Message();
38+
39+
$parser = new Parser();
40+
$parser->parseChunk($data, $request);
41+
42+
$header = $request->header;
43+
$this->assertSame(0x7262, $header->get('id'));
44+
$this->assertSame(1, $header->get('qdCount'));
45+
$this->assertSame(0, $header->get('anCount'));
46+
$this->assertSame(0, $header->get('nsCount'));
47+
$this->assertSame(0, $header->get('arCount'));
48+
$this->assertSame(0, $header->get('qr'));
49+
$this->assertSame(Message::OPCODE_QUERY, $header->get('opcode'));
50+
$this->assertSame(0, $header->get('aa'));
51+
$this->assertSame(0, $header->get('tc'));
52+
$this->assertSame(1, $header->get('rd'));
53+
$this->assertSame(0, $header->get('ra'));
54+
$this->assertSame(0, $header->get('z'));
55+
$this->assertSame(Message::RCODE_OK, $header->get('rcode'));
56+
57+
$this->assertCount(1, $request->questions);
58+
$this->assertSame('igor.io', $request->questions[0]['name']);
59+
$this->assertSame(Message::TYPE_A, $request->questions[0]['type']);
60+
$this->assertSame(Message::CLASS_IN, $request->questions[0]['class']);
61+
}
62+
63+
public function testParseResponse()
64+
{
65+
$data = "";
66+
$data .= "72 62 81 80 00 01 00 01 00 00 00 00"; // header
67+
$data .= "04 69 67 6f 72 02 69 6f 00"; // question: igor.io
68+
$data .= "00 01 00 01"; // question: type A, class IN
69+
$data .= "c0 0c"; // answer: offset pointer to igor.io
70+
$data .= "00 01 00 01"; // answer: type A, class IN
71+
$data .= "00 01 51 80"; // answer: ttl 86400
72+
$data .= "00 04"; // answer: rdlength 4
73+
$data .= "b2 4f a9 83"; // answer: rdata 178.79.169.131
74+
75+
$data = $this->convertTcpDumpToBinary($data);
76+
77+
$response = new Message();
78+
79+
$parser = new Parser();
80+
$parser->parseChunk($data, $response);
81+
82+
$header = $response->header;
83+
$this->assertSame(0x7262, $header->get('id'));
84+
$this->assertSame(1, $header->get('qdCount'));
85+
$this->assertSame(1, $header->get('anCount'));
86+
$this->assertSame(0, $header->get('nsCount'));
87+
$this->assertSame(0, $header->get('arCount'));
88+
$this->assertSame(1, $header->get('qr'));
89+
$this->assertSame(Message::OPCODE_QUERY, $header->get('opcode'));
90+
$this->assertSame(0, $header->get('aa'));
91+
$this->assertSame(0, $header->get('tc'));
92+
$this->assertSame(1, $header->get('rd'));
93+
$this->assertSame(1, $header->get('ra'));
94+
$this->assertSame(0, $header->get('z'));
95+
$this->assertSame(Message::RCODE_OK, $header->get('rcode'));
96+
97+
$this->assertCount(1, $response->questions);
98+
$this->assertSame('igor.io', $response->questions[0]['name']);
99+
$this->assertSame(Message::TYPE_A, $response->questions[0]['type']);
100+
$this->assertSame(Message::CLASS_IN, $response->questions[0]['class']);
101+
102+
$this->assertCount(1, $response->answers);
103+
$this->assertSame('igor.io', $response->answers[0]->name);
104+
$this->assertSame(Message::TYPE_A, $response->answers[0]->type);
105+
$this->assertSame(Message::CLASS_IN, $response->answers[0]->class);
106+
$this->assertSame(86400, $response->answers[0]->ttl);
107+
$this->assertSame('178.79.169.131', $response->answers[0]->data);
108+
}
109+
110+
public function testParseQuestionWithTwoQuestions()
111+
{
112+
$data = "";
113+
$data .= "04 69 67 6f 72 02 69 6f 00"; // question: igor.io
114+
$data .= "00 01 00 01"; // question: type A, class IN
115+
$data .= "03 77 77 77 04 69 67 6f 72 02 69 6f 00"; // question: www.igor.io
116+
$data .= "00 01 00 01"; // question: type A, class IN
117+
118+
$data = $this->convertTcpDumpToBinary($data);
119+
120+
$request = new Message();
121+
$request->header->set('qdCount', 2);
122+
$request->data = $data;
123+
124+
$parser = new Parser();
125+
$parser->parseQuestion($request);
126+
127+
$this->assertCount(2, $request->questions);
128+
$this->assertSame('igor.io', $request->questions[0]['name']);
129+
$this->assertSame(Message::TYPE_A, $request->questions[0]['type']);
130+
$this->assertSame(Message::CLASS_IN, $request->questions[0]['class']);
131+
$this->assertSame('www.igor.io', $request->questions[1]['name']);
132+
$this->assertSame(Message::TYPE_A, $request->questions[1]['type']);
133+
$this->assertSame(Message::CLASS_IN, $request->questions[1]['class']);
134+
}
135+
136+
public function testParseAnswerWithInlineData()
137+
{
138+
$data = "";
139+
$data .= "04 69 67 6f 72 02 69 6f 00"; // answer: igor.io
140+
$data .= "00 01 00 01"; // answer: type A, class IN
141+
$data .= "00 01 51 80"; // answer: ttl 86400
142+
$data .= "00 04"; // answer: rdlength 4
143+
$data .= "b2 4f a9 83"; // answer: rdata 178.79.169.131
144+
145+
$data = $this->convertTcpDumpToBinary($data);
146+
147+
$response = new Message();
148+
$response->header->set('anCount', 1);
149+
$response->data = $data;
150+
151+
$parser = new Parser();
152+
$parser->parseAnswer($response);
153+
154+
$this->assertCount(1, $response->answers);
155+
$this->assertSame('igor.io', $response->answers[0]->name);
156+
$this->assertSame(Message::TYPE_A, $response->answers[0]->type);
157+
$this->assertSame(Message::CLASS_IN, $response->answers[0]->class);
158+
$this->assertSame(86400, $response->answers[0]->ttl);
159+
$this->assertSame('178.79.169.131', $response->answers[0]->data);
160+
}
161+
162+
public function testParseResponseWithCnameAndOffsetPointers()
163+
{
164+
$data = "";
165+
$data .= "9e 8d 81 80 00 01 00 01 00 00 00 00"; // header
166+
$data .= "04 6d 61 69 6c 06 67 6f 6f 67 6c 65 03 63 6f 6d 00"; // question: mail.google.com
167+
$data .= "00 05 00 01"; // question: type CNAME, class IN
168+
$data .= "c0 0c"; // answer: offset pointer to mail.google.com
169+
$data .= "00 05 00 01"; // answer: type CNAME, class IN
170+
$data .= "00 00 a8 9c"; // answer: ttl 43164
171+
$data .= "00 0f"; // answer: rdlength 15
172+
$data .= "0a 67 6f 6f 67 6c 65 6d 61 69 6c 01 6c"; // answer: rdata googlemail.l.
173+
$data .= "c0 11"; // answer: rdata offset pointer to google.com
174+
175+
$data = $this->convertTcpDumpToBinary($data);
176+
177+
$response = new Message();
178+
179+
$parser = new Parser();
180+
$parser->parseChunk($data, $response);
181+
182+
$this->assertCount(1, $response->questions);
183+
$this->assertSame('mail.google.com', $response->questions[0]['name']);
184+
$this->assertSame(Message::TYPE_CNAME, $response->questions[0]['type']);
185+
$this->assertSame(Message::CLASS_IN, $response->questions[0]['class']);
186+
187+
$this->assertCount(1, $response->answers);
188+
$this->assertSame('mail.google.com', $response->answers[0]->name);
189+
$this->assertSame(Message::TYPE_CNAME, $response->answers[0]->type);
190+
$this->assertSame(Message::CLASS_IN, $response->answers[0]->class);
191+
$this->assertSame(43164, $response->answers[0]->ttl);
192+
$this->assertSame('googlemail.l.google.com', $response->answers[0]->data);
193+
}
194+
195+
public function testParseResponseWithTwoAnswers()
196+
{
197+
$data = "";
198+
$data .= "bc 73 81 80 00 01 00 02 00 00 00 00"; // header
199+
$data .= "02 69 6f 0d 77 68 6f 69 73 2d 73 65 72 76 65 72 73 03 6e 65 74 00";
200+
// question: io.whois-servers.net
201+
$data .= "00 01 00 01"; // question: type A, class IN
202+
$data .= "c0 0c"; // answer: offset pointer to io.whois-servers.net
203+
$data .= "00 05 00 01"; // answer: type CNAME, class IN
204+
$data .= "00 00 00 29"; // answer: ttl 41
205+
$data .= "00 0e"; // answer: rdlength 14
206+
$data .= "05 77 68 6f 69 73 03 6e 69 63 02 69 6f 00"; // answer: rdata whois.nic.io
207+
$data .= "c0 32"; // answer: offset pointer to whois.nic.io
208+
$data .= "00 01 00 01"; // answer: type CNAME, class IN
209+
$data .= "00 00 0d f7"; // answer: ttl 3575
210+
$data .= "00 04"; // answer: rdlength 4
211+
$data .= "c1 df 4e 98"; // answer: rdata 193.223.78.152
212+
213+
$data = $this->convertTcpDumpToBinary($data);
214+
215+
$response = new Message();
216+
217+
$parser = new Parser();
218+
$parser->parseChunk($data, $response);
219+
220+
$this->assertCount(1, $response->questions);
221+
$this->assertSame('io.whois-servers.net', $response->questions[0]['name']);
222+
$this->assertSame(Message::TYPE_A, $response->questions[0]['type']);
223+
$this->assertSame(Message::CLASS_IN, $response->questions[0]['class']);
224+
225+
$this->assertCount(2, $response->answers);
226+
227+
$this->assertSame('io.whois-servers.net', $response->answers[0]->name);
228+
$this->assertSame(Message::TYPE_CNAME, $response->answers[0]->type);
229+
$this->assertSame(Message::CLASS_IN, $response->answers[0]->class);
230+
$this->assertSame(41, $response->answers[0]->ttl);
231+
$this->assertSame('whois.nic.io', $response->answers[0]->data);
232+
233+
$this->assertSame('whois.nic.io', $response->answers[1]->name);
234+
$this->assertSame(Message::TYPE_A, $response->answers[1]->type);
235+
$this->assertSame(Message::CLASS_IN, $response->answers[1]->class);
236+
$this->assertSame(3575, $response->answers[1]->ttl);
237+
$this->assertSame('193.223.78.152', $response->answers[1]->data);
238+
}
239+
240+
private function convertTcpDumpToBinary($input)
241+
{
242+
// sudo ngrep -d en1 -x port 53
243+
244+
return pack('H*', str_replace(' ', '', $input));
245+
}
246+
}

0 commit comments

Comments
 (0)