test-sftp.js 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313
  1. var SFTPStream = require('../lib/sftp');
  2. var Stats = SFTPStream.Stats;
  3. var STATUS_CODE = SFTPStream.STATUS_CODE;
  4. var OPEN_MODE = SFTPStream.OPEN_MODE;
  5. var constants = require('constants');
  6. var basename = require('path').basename;
  7. var assert = require('assert');
  8. var group = basename(__filename, '.js') + '/';
  9. var t = -1;
  10. var tests = [
  11. // successful client requests
  12. { run: function() {
  13. setup(this);
  14. var self = this;
  15. var what = this.what;
  16. var client = this.client;
  17. var server = this.server;
  18. this.onReady = function() {
  19. var path_ = '/tmp/foo.txt';
  20. var handle_ = Buffer.from('node.js');
  21. server.on('OPEN', function(id, path, pflags, attrs) {
  22. assert(++self.state.requests === 1,
  23. makeMsg(what, 'Saw too many requests'));
  24. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  25. assert(path === path_, makeMsg(what, 'Wrong path: ' + path));
  26. assert(pflags === (OPEN_MODE.TRUNC
  27. | OPEN_MODE.CREAT
  28. | OPEN_MODE.WRITE),
  29. makeMsg(what, 'Wrong flags: ' + flagsToHuman(pflags)));
  30. server.handle(id, handle_);
  31. server.end();
  32. });
  33. client.open(path_, 'w', function(err, handle) {
  34. assert(++self.state.responses === 1,
  35. makeMsg(what, 'Saw too many responses'));
  36. assert(!err, makeMsg(what, 'Unexpected open() error: ' + err));
  37. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  38. });
  39. };
  40. },
  41. what: 'open'
  42. },
  43. { run: function() {
  44. setup(this);
  45. var self = this;
  46. var what = this.what;
  47. var client = this.client;
  48. var server = this.server;
  49. this.onReady = function() {
  50. var handle_ = Buffer.from('node.js');
  51. server.on('CLOSE', function(id, handle) {
  52. assert(++self.state.requests === 1,
  53. makeMsg(what, 'Saw too many requests'));
  54. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  55. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  56. server.status(id, STATUS_CODE.OK);
  57. server.end();
  58. });
  59. client.close(handle_, function(err) {
  60. assert(++self.state.responses === 1,
  61. makeMsg(what, 'Saw too many responses'));
  62. assert(!err, makeMsg(what, 'Unexpected close() error: ' + err));
  63. });
  64. };
  65. },
  66. what: 'close'
  67. },
  68. { run: function() {
  69. setup(this);
  70. var self = this;
  71. var what = this.what;
  72. var client = this.client;
  73. var server = this.server;
  74. this.onReady = function() {
  75. var handle_ = Buffer.from('node.js');
  76. var expected =
  77. Buffer.from('node.jsnode.jsnode.jsnode.jsnode.jsnode.js');
  78. var buffer = Buffer.alloc(expected.length);
  79. server.on('READ', function(id, handle, offset, len) {
  80. assert(++self.state.requests <= 2,
  81. makeMsg(what, 'Saw too many requests'));
  82. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  83. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  84. assert(offset === 5, makeMsg(what, 'Wrong read offset: ' + offset));
  85. assert(len === buffer.length,
  86. makeMsg(what, 'Wrong read len: ' + len));
  87. server.data(id, expected);
  88. server.end();
  89. });
  90. client.readData(handle_, buffer, 0, buffer.length, 5, clientReadCb);
  91. function clientReadCb(err, nb) {
  92. assert(++self.state.responses <= 2,
  93. makeMsg(what, 'Saw too many responses'));
  94. assert(!err, makeMsg(what, 'Unexpected readData() error: ' + err));
  95. assert.deepEqual(buffer,
  96. expected,
  97. makeMsg(what, 'read data mismatch'));
  98. }
  99. };
  100. },
  101. what: 'readData'
  102. },
  103. { run: function() {
  104. setup(this);
  105. var self = this;
  106. var what = this.what;
  107. var client = this.client;
  108. var server = this.server;
  109. this.onReady = function() {
  110. var handle_ = Buffer.from('node.js');
  111. var buf = Buffer.from('node.jsnode.jsnode.jsnode.jsnode.jsnode.js');
  112. server.on('WRITE', function(id, handle, offset, data) {
  113. assert(++self.state.requests === 1,
  114. makeMsg(what, 'Saw too many requests'));
  115. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  116. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  117. assert(offset === 5, makeMsg(what, 'Wrong write offset: ' + offset));
  118. assert.deepEqual(data, buf, makeMsg(what, 'write data mismatch'));
  119. server.status(id, STATUS_CODE.OK);
  120. server.end();
  121. });
  122. client.writeData(handle_, buf, 0, buf.length, 5, function(err, nb) {
  123. assert(++self.state.responses === 1,
  124. makeMsg(what, 'Saw too many responses'));
  125. assert(!err, makeMsg(what, 'Unexpected writeData() error: ' + err));
  126. assert.equal(nb, buf.length);
  127. });
  128. };
  129. },
  130. what: 'write'
  131. },
  132. { run: function() {
  133. setup(this);
  134. var self = this;
  135. var what = this.what;
  136. var client = this.client;
  137. var server = this.server;
  138. this.onReady = function() {
  139. var handle_ = Buffer.from('node.js');
  140. var buf = Buffer.allocUnsafe(3 * 32 * 1024);
  141. server.on('WRITE', function(id, handle, offset, data) {
  142. ++self.state.requests;
  143. assert.equal(id,
  144. self.state.requests - 1,
  145. makeMsg(what, 'Wrong request id: ' + id));
  146. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  147. assert.equal(offset,
  148. (self.state.requests - 1) * 32 * 1024,
  149. makeMsg(what, 'Wrong write offset: ' + offset));
  150. assert((offset + data.length) <= buf.length);
  151. assert.deepEqual(data,
  152. buf.slice(offset, offset + data.length),
  153. makeMsg(what, 'write data mismatch'));
  154. server.status(id, STATUS_CODE.OK);
  155. if (self.state.requests === 3)
  156. server.end();
  157. });
  158. client.writeData(handle_, buf, 0, buf.length, 0, function(err, nb) {
  159. ++self.state.responses;
  160. assert(!err, makeMsg(what, 'Unexpected writeData() error: ' + err));
  161. assert.equal(nb, buf.length);
  162. });
  163. };
  164. },
  165. expected: {
  166. requests: 3,
  167. responses: 1
  168. },
  169. what: 'write (overflow)'
  170. },
  171. { run: function() {
  172. setup(this);
  173. var self = this;
  174. var what = this.what;
  175. var client = this.client;
  176. var server = this.server;
  177. this.onReady = function() {
  178. var path_ = '/foo/bar/baz';
  179. var attrs_ = new Stats({
  180. size: 10 * 1024,
  181. uid: 9001,
  182. gid: 9001,
  183. atime: (Date.now() / 1000) | 0,
  184. mtime: (Date.now() / 1000) | 0
  185. });
  186. server.on('LSTAT', function(id, path) {
  187. assert(++self.state.requests === 1,
  188. makeMsg(what, 'Saw too many requests'));
  189. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  190. assert(path === path_, makeMsg(what, 'Wrong path: ' + path));
  191. server.attrs(id, attrs_);
  192. server.end();
  193. });
  194. client.lstat(path_, function(err, attrs) {
  195. assert(++self.state.responses === 1,
  196. makeMsg(what, 'Saw too many responses'));
  197. assert(!err, makeMsg(what, 'Unexpected lstat() error: ' + err));
  198. assert.deepEqual(attrs, attrs_, makeMsg(what, 'attrs mismatch'));
  199. });
  200. };
  201. },
  202. what: 'lstat'
  203. },
  204. { run: function() {
  205. setup(this);
  206. var self = this;
  207. var what = this.what;
  208. var client = this.client;
  209. var server = this.server;
  210. this.onReady = function() {
  211. var handle_ = Buffer.from('node.js');
  212. var attrs_ = new Stats({
  213. size: 10 * 1024,
  214. uid: 9001,
  215. gid: 9001,
  216. atime: (Date.now() / 1000) | 0,
  217. mtime: (Date.now() / 1000) | 0
  218. });
  219. server.on('FSTAT', function(id, handle) {
  220. assert(++self.state.requests === 1,
  221. makeMsg(what, 'Saw too many requests'));
  222. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  223. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  224. server.attrs(id, attrs_);
  225. server.end();
  226. });
  227. client.fstat(handle_, function(err, attrs) {
  228. assert(++self.state.responses === 1,
  229. makeMsg(what, 'Saw too many responses'));
  230. assert(!err, makeMsg(what, 'Unexpected fstat() error: ' + err));
  231. assert.deepEqual(attrs, attrs_, makeMsg(what, 'attrs mismatch'));
  232. });
  233. };
  234. },
  235. what: 'fstat'
  236. },
  237. { run: function() {
  238. setup(this);
  239. var self = this;
  240. var what = this.what;
  241. var client = this.client;
  242. var server = this.server;
  243. this.onReady = function() {
  244. var path_ = '/foo/bar/baz';
  245. var attrs_ = new Stats({
  246. uid: 9001,
  247. gid: 9001,
  248. atime: (Date.now() / 1000) | 0,
  249. mtime: (Date.now() / 1000) | 0
  250. });
  251. server.on('SETSTAT', function(id, path, attrs) {
  252. assert(++self.state.requests === 1,
  253. makeMsg(what, 'Saw too many requests'));
  254. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  255. assert(path === path_, makeMsg(what, 'Wrong path: ' + path));
  256. assert.deepEqual(attrs, attrs_, makeMsg(what, 'attrs mismatch'));
  257. server.status(id, STATUS_CODE.OK);
  258. server.end();
  259. });
  260. client.setstat(path_, attrs_, function(err) {
  261. assert(++self.state.responses === 1,
  262. makeMsg(what, 'Saw too many responses'));
  263. assert(!err, makeMsg(what, 'Unexpected setstat() error: ' + err));
  264. });
  265. };
  266. },
  267. what: 'setstat'
  268. },
  269. { run: function() {
  270. setup(this);
  271. var self = this;
  272. var what = this.what;
  273. var client = this.client;
  274. var server = this.server;
  275. this.onReady = function() {
  276. var handle_ = Buffer.from('node.js');
  277. var attrs_ = new Stats({
  278. uid: 9001,
  279. gid: 9001,
  280. atime: (Date.now() / 1000) | 0,
  281. mtime: (Date.now() / 1000) | 0
  282. });
  283. server.on('FSETSTAT', function(id, handle, attrs) {
  284. assert(++self.state.requests === 1,
  285. makeMsg(what, 'Saw too many requests'));
  286. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  287. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  288. assert.deepEqual(attrs, attrs_, makeMsg(what, 'attrs mismatch'));
  289. server.status(id, STATUS_CODE.OK);
  290. server.end();
  291. });
  292. client.fsetstat(handle_, attrs_, function(err) {
  293. assert(++self.state.responses === 1,
  294. makeMsg(what, 'Saw too many responses'));
  295. assert(!err, makeMsg(what, 'Unexpected fsetstat() error: ' + err));
  296. });
  297. };
  298. },
  299. what: 'fsetstat'
  300. },
  301. { run: function() {
  302. setup(this);
  303. var self = this;
  304. var what = this.what;
  305. var client = this.client;
  306. var server = this.server;
  307. this.onReady = function() {
  308. var handle_ = Buffer.from('node.js');
  309. var path_ = '/tmp';
  310. server.on('OPENDIR', function(id, path) {
  311. assert(++self.state.requests === 1,
  312. makeMsg(what, 'Saw too many requests'));
  313. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  314. assert(path === path_, makeMsg(what, 'Wrong path: ' + path));
  315. server.handle(id, handle_);
  316. server.end();
  317. });
  318. client.opendir(path_, function(err, handle) {
  319. assert(++self.state.responses === 1,
  320. makeMsg(what, 'Saw too many responses'));
  321. assert(!err, makeMsg(what, 'Unexpected opendir() error: ' + err));
  322. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  323. });
  324. };
  325. },
  326. what: 'opendir'
  327. },
  328. { run: function() {
  329. setup(this);
  330. var self = this;
  331. var what = this.what;
  332. var client = this.client;
  333. var server = this.server;
  334. this.onReady = function() {
  335. var handle_ = Buffer.from('node.js');
  336. var list_ = [
  337. { filename: '.',
  338. longname: 'drwxr-xr-x 56 nodejs nodejs 4096 Nov 10 01:05 .',
  339. attrs: new Stats({
  340. mode: 0755 | constants.S_IFDIR,
  341. size: 4096,
  342. uid: 9001,
  343. gid: 8001,
  344. atime: 1415599549,
  345. mtime: 1415599590
  346. })
  347. },
  348. { filename: '..',
  349. longname: 'drwxr-xr-x 4 root root 4096 May 16 2013 ..',
  350. attrs: new Stats({
  351. mode: 0755 | constants.S_IFDIR,
  352. size: 4096,
  353. uid: 0,
  354. gid: 0,
  355. atime: 1368729954,
  356. mtime: 1368729999
  357. })
  358. },
  359. { filename: 'foo',
  360. longname: 'drwxrwxrwx 2 nodejs nodejs 4096 Mar 8 2009 foo',
  361. attrs: new Stats({
  362. mode: 0777 | constants.S_IFDIR,
  363. size: 4096,
  364. uid: 9001,
  365. gid: 8001,
  366. atime: 1368729954,
  367. mtime: 1368729999
  368. })
  369. },
  370. { filename: 'bar',
  371. longname: '-rw-r--r-- 1 nodejs nodejs 513901992 Dec 4 2009 bar',
  372. attrs: new Stats({
  373. mode: 0644 | constants.S_IFREG,
  374. size: 513901992,
  375. uid: 9001,
  376. gid: 8001,
  377. atime: 1259972199,
  378. mtime: 1259972199
  379. })
  380. }
  381. ];
  382. server.on('READDIR', function(id, handle) {
  383. assert(++self.state.requests === 1,
  384. makeMsg(what, 'Saw too many requests'));
  385. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  386. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  387. server.name(id, list_);
  388. server.end();
  389. });
  390. client.readdir(handle_, function(err, list) {
  391. assert(++self.state.responses === 1,
  392. makeMsg(what, 'Saw too many responses'));
  393. assert(!err, makeMsg(what, 'Unexpected readdir() error: ' + err));
  394. assert.deepEqual(list,
  395. list_.slice(2),
  396. makeMsg(what, 'dir list mismatch'));
  397. });
  398. };
  399. },
  400. what: 'readdir'
  401. },
  402. { run: function() {
  403. setup(this);
  404. var self = this;
  405. var what = this.what;
  406. var client = this.client;
  407. var server = this.server;
  408. this.onReady = function() {
  409. var handle_ = Buffer.from('node.js');
  410. var list_ = [
  411. { filename: '.',
  412. longname: 'drwxr-xr-x 56 nodejs nodejs 4096 Nov 10 01:05 .',
  413. attrs: new Stats({
  414. mode: 0755 | constants.S_IFDIR,
  415. size: 4096,
  416. uid: 9001,
  417. gid: 8001,
  418. atime: 1415599549,
  419. mtime: 1415599590
  420. })
  421. },
  422. { filename: '..',
  423. longname: 'drwxr-xr-x 4 root root 4096 May 16 2013 ..',
  424. attrs: new Stats({
  425. mode: 0755 | constants.S_IFDIR,
  426. size: 4096,
  427. uid: 0,
  428. gid: 0,
  429. atime: 1368729954,
  430. mtime: 1368729999
  431. })
  432. },
  433. { filename: 'foo',
  434. longname: 'drwxrwxrwx 2 nodejs nodejs 4096 Mar 8 2009 foo',
  435. attrs: new Stats({
  436. mode: 0777 | constants.S_IFDIR,
  437. size: 4096,
  438. uid: 9001,
  439. gid: 8001,
  440. atime: 1368729954,
  441. mtime: 1368729999
  442. })
  443. },
  444. { filename: 'bar',
  445. longname: '-rw-r--r-- 1 nodejs nodejs 513901992 Dec 4 2009 bar',
  446. attrs: new Stats({
  447. mode: 0644 | constants.S_IFREG,
  448. size: 513901992,
  449. uid: 9001,
  450. gid: 8001,
  451. atime: 1259972199,
  452. mtime: 1259972199
  453. })
  454. }
  455. ];
  456. server.on('READDIR', function(id, handle) {
  457. assert(++self.state.requests === 1,
  458. makeMsg(what, 'Saw too many requests'));
  459. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  460. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  461. server.name(id, list_);
  462. server.end();
  463. });
  464. client.readdir(handle_, { full: true }, function(err, list) {
  465. assert(++self.state.responses === 1,
  466. makeMsg(what, 'Saw too many responses'));
  467. assert(!err, makeMsg(what, 'Unexpected readdir() error: ' + err));
  468. assert.deepEqual(list, list_, makeMsg(what, 'dir list mismatch'));
  469. });
  470. };
  471. },
  472. what: 'readdir (full)'
  473. },
  474. { run: function() {
  475. setup(this);
  476. var self = this;
  477. var what = this.what;
  478. var client = this.client;
  479. var server = this.server;
  480. this.onReady = function() {
  481. var path_ = '/foo/bar/baz';
  482. server.on('REMOVE', function(id, path) {
  483. assert(++self.state.requests === 1,
  484. makeMsg(what, 'Saw too many requests'));
  485. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  486. assert(path === path_, makeMsg(what, 'Wrong path: ' + path));
  487. server.status(id, STATUS_CODE.OK);
  488. server.end();
  489. });
  490. client.unlink(path_, function(err) {
  491. assert(++self.state.responses === 1,
  492. makeMsg(what, 'Saw too many responses'));
  493. assert(!err, makeMsg(what, 'Unexpected unlink() error: ' + err));
  494. });
  495. };
  496. },
  497. what: 'remove'
  498. },
  499. { run: function() {
  500. setup(this);
  501. var self = this;
  502. var what = this.what;
  503. var client = this.client;
  504. var server = this.server;
  505. this.onReady = function() {
  506. var path_ = '/foo/bar/baz';
  507. server.on('MKDIR', function(id, path) {
  508. assert(++self.state.requests === 1,
  509. makeMsg(what, 'Saw too many requests'));
  510. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  511. assert(path === path_, makeMsg(what, 'Wrong path: ' + path));
  512. server.status(id, STATUS_CODE.OK);
  513. server.end();
  514. });
  515. client.mkdir(path_, function(err) {
  516. assert(++self.state.responses === 1,
  517. makeMsg(what, 'Saw too many responses'));
  518. assert(!err, makeMsg(what, 'Unexpected mkdir() error: ' + err));
  519. });
  520. };
  521. },
  522. what: 'mkdir'
  523. },
  524. { run: function() {
  525. setup(this);
  526. var self = this;
  527. var what = this.what;
  528. var client = this.client;
  529. var server = this.server;
  530. this.onReady = function() {
  531. var path_ = '/foo/bar/baz';
  532. server.on('RMDIR', function(id, path) {
  533. assert(++self.state.requests === 1,
  534. makeMsg(what, 'Saw too many requests'));
  535. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  536. assert(path === path_, makeMsg(what, 'Wrong path: ' + path));
  537. server.status(id, STATUS_CODE.OK);
  538. server.end();
  539. });
  540. client.rmdir(path_, function(err) {
  541. assert(++self.state.responses === 1,
  542. makeMsg(what, 'Saw too many responses'));
  543. assert(!err, makeMsg(what, 'Unexpected rmdir() error: ' + err));
  544. });
  545. };
  546. },
  547. what: 'rmdir'
  548. },
  549. { run: function() {
  550. setup(this);
  551. var self = this;
  552. var what = this.what;
  553. var client = this.client;
  554. var server = this.server;
  555. this.onReady = function() {
  556. var path_ = '/foo/bar/baz';
  557. var name_ = { filename: '/tmp/foo' };
  558. server.on('REALPATH', function(id, path) {
  559. assert(++self.state.requests === 1,
  560. makeMsg(what, 'Saw too many requests'));
  561. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  562. assert(path === path_, makeMsg(what, 'Wrong path: ' + path));
  563. server.name(id, name_);
  564. server.end();
  565. });
  566. client.realpath(path_, function(err, name) {
  567. assert(++self.state.responses === 1,
  568. makeMsg(what, 'Saw too many responses'));
  569. assert(!err, makeMsg(what, 'Unexpected realpath() error: ' + err));
  570. assert.deepEqual(name,
  571. name_.filename,
  572. makeMsg(what, 'name mismatch'));
  573. });
  574. };
  575. },
  576. what: 'realpath'
  577. },
  578. { run: function() {
  579. setup(this);
  580. var self = this;
  581. var what = this.what;
  582. var client = this.client;
  583. var server = this.server;
  584. this.onReady = function() {
  585. var path_ = '/foo/bar/baz';
  586. var attrs_ = new Stats({
  587. size: 10 * 1024,
  588. uid: 9001,
  589. gid: 9001,
  590. atime: (Date.now() / 1000) | 0,
  591. mtime: (Date.now() / 1000) | 0
  592. });
  593. server.on('STAT', function(id, path) {
  594. assert(++self.state.requests === 1,
  595. makeMsg(what, 'Saw too many requests'));
  596. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  597. assert(path === path_, makeMsg(what, 'Wrong path: ' + path));
  598. server.attrs(id, attrs_);
  599. server.end();
  600. });
  601. client.stat(path_, function(err, attrs) {
  602. assert(++self.state.responses === 1,
  603. makeMsg(what, 'Saw too many responses'));
  604. assert(!err, makeMsg(what, 'Unexpected stat() error: ' + err));
  605. assert.deepEqual(attrs, attrs_, makeMsg(what, 'attrs mismatch'));
  606. });
  607. };
  608. },
  609. what: 'stat'
  610. },
  611. { run: function() {
  612. setup(this);
  613. var self = this;
  614. var what = this.what;
  615. var client = this.client;
  616. var server = this.server;
  617. this.onReady = function() {
  618. var oldPath_ = '/foo/bar/baz';
  619. var newPath_ = '/tmp/foo';
  620. server.on('RENAME', function(id, oldPath, newPath) {
  621. assert(++self.state.requests === 1,
  622. makeMsg(what, 'Saw too many requests'));
  623. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  624. assert(oldPath === oldPath_,
  625. makeMsg(what, 'Wrong old path: ' + oldPath));
  626. assert(newPath === newPath_,
  627. makeMsg(what, 'Wrong new path: ' + newPath));
  628. server.status(id, STATUS_CODE.OK);
  629. server.end();
  630. });
  631. client.rename(oldPath_, newPath_, function(err) {
  632. assert(++self.state.responses === 1,
  633. makeMsg(what, 'Saw too many responses'));
  634. assert(!err, makeMsg(what, 'Unexpected rename() error: ' + err));
  635. });
  636. };
  637. },
  638. what: 'rename'
  639. },
  640. { run: function() {
  641. setup(this);
  642. var self = this;
  643. var what = this.what;
  644. var client = this.client;
  645. var server = this.server;
  646. this.onReady = function() {
  647. var linkPath_ = '/foo/bar/baz';
  648. var name = { filename: '/tmp/foo' };
  649. server.on('READLINK', function(id, linkPath) {
  650. assert(++self.state.requests === 1,
  651. makeMsg(what, 'Saw too many requests'));
  652. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  653. assert(linkPath === linkPath_,
  654. makeMsg(what, 'Wrong link path: ' + linkPath));
  655. server.name(id, name);
  656. server.end();
  657. });
  658. client.readlink(linkPath_, function(err, targetPath) {
  659. assert(++self.state.responses === 1,
  660. makeMsg(what, 'Saw too many responses'));
  661. assert(!err, makeMsg(what, 'Unexpected readlink() error: ' + err));
  662. assert(targetPath === name.filename,
  663. makeMsg(what, 'Wrong target path: ' + targetPath));
  664. });
  665. };
  666. },
  667. what: 'readlink'
  668. },
  669. { run: function() {
  670. setup(this);
  671. var self = this;
  672. var what = this.what;
  673. var client = this.client;
  674. var server = this.server;
  675. this.onReady = function() {
  676. var linkPath_ = '/foo/bar/baz';
  677. var targetPath_ = '/tmp/foo';
  678. server.on('SYMLINK', function(id, linkPath, targetPath) {
  679. assert(++self.state.requests === 1,
  680. makeMsg(what, 'Saw too many requests'));
  681. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  682. assert(linkPath === linkPath_,
  683. makeMsg(what, 'Wrong link path: ' + linkPath));
  684. assert(targetPath === targetPath_,
  685. makeMsg(what, 'Wrong target path: ' + targetPath));
  686. server.status(id, STATUS_CODE.OK);
  687. server.end();
  688. });
  689. client.symlink(targetPath_, linkPath_, function(err) {
  690. assert(++self.state.responses === 1,
  691. makeMsg(what, 'Saw too many responses'));
  692. assert(!err, makeMsg(what, 'Unexpected symlink() error: ' + err));
  693. });
  694. };
  695. },
  696. what: 'symlink'
  697. },
  698. { run: function() {
  699. setup(this);
  700. var self = this;
  701. var what = this.what;
  702. var client = this.client;
  703. var server = this.server;
  704. this.onReady = function() {
  705. var path_ = '/foo/bar/baz';
  706. var handle_ = Buffer.from('hi mom!');
  707. var data_ = Buffer.from('hello world');
  708. server.once('OPEN', function(id, path, pflags, attrs) {
  709. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  710. assert(path === path_, makeMsg(what, 'Wrong path: ' + path));
  711. assert(pflags === OPEN_MODE.READ,
  712. makeMsg(what, 'Wrong flags: ' + flagsToHuman(pflags)));
  713. server.handle(id, handle_);
  714. }).once('FSTAT', function(id, handle) {
  715. assert(id === 1, makeMsg(what, 'Wrong request id: ' + id));
  716. var attrs = new Stats({
  717. size: data_.length,
  718. uid: 9001,
  719. gid: 9001,
  720. atime: (Date.now() / 1000) | 0,
  721. mtime: (Date.now() / 1000) | 0
  722. });
  723. server.attrs(id, attrs);
  724. }).once('READ', function(id, handle, offset, len) {
  725. assert(id === 2, makeMsg(what, 'Wrong request id: ' + id));
  726. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  727. assert(offset === 0, makeMsg(what, 'Wrong read offset: ' + offset));
  728. server.data(id, data_);
  729. }).once('CLOSE', function(id, handle) {
  730. ++self.state.requests;
  731. assert(id === 3, makeMsg(what, 'Wrong request id: ' + id));
  732. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  733. server.status(id, STATUS_CODE.OK);
  734. server.end();
  735. });
  736. client.readFile(path_, function(err, buf) {
  737. ++self.state.responses;
  738. assert(!err, makeMsg(what, 'Unexpected error: ' + err));
  739. assert.deepEqual(buf, data_, makeMsg(what, 'data mismatch'));
  740. });
  741. };
  742. },
  743. what: 'readFile'
  744. },
  745. { run: function() {
  746. setup(this);
  747. var self = this;
  748. var what = this.what;
  749. var client = this.client;
  750. var server = this.server;
  751. this.onReady = function() {
  752. var path_ = '/foo/bar/baz';
  753. var handle_ = Buffer.from('hi mom!');
  754. var data_ = Buffer.from('hello world');
  755. var reads = 0;
  756. server.once('OPEN', function(id, path, pflags, attrs) {
  757. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  758. assert(path === path_, makeMsg(what, 'Wrong path: ' + path));
  759. assert(pflags === OPEN_MODE.READ,
  760. makeMsg(what, 'Wrong flags: ' + flagsToHuman(pflags)));
  761. server.handle(id, handle_);
  762. }).once('FSTAT', function(id, handle) {
  763. assert(id === 1, makeMsg(what, 'Wrong request id: ' + id));
  764. var attrs = new Stats({
  765. uid: 9001,
  766. gid: 9001,
  767. atime: (Date.now() / 1000) | 0,
  768. mtime: (Date.now() / 1000) | 0
  769. });
  770. server.attrs(id, attrs);
  771. }).on('READ', function(id, handle, offset, len) {
  772. assert(++reads <= 2, makeMsg(what, 'Saw too many READs'));
  773. assert(id === 2 || id === 3,
  774. makeMsg(what, 'Wrong request id: ' + id));
  775. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  776. switch(id) {
  777. case 2:
  778. assert(offset === 0,
  779. makeMsg(what,
  780. 'Wrong read offset for first read: ' + offset));
  781. server.data(id, data_);
  782. break;
  783. case 3:
  784. assert(offset === data_.length,
  785. makeMsg(what,
  786. 'Wrong read offset for second read: ' + offset));
  787. server.status(id, STATUS_CODE.EOF);
  788. break;
  789. }
  790. }).once('CLOSE', function(id, handle) {
  791. ++self.state.requests;
  792. assert(id === 4, makeMsg(what, 'Wrong request id: ' + id));
  793. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  794. server.status(id, STATUS_CODE.OK);
  795. server.end();
  796. });
  797. client.readFile(path_, function(err, buf) {
  798. ++self.state.responses;
  799. assert(!err, makeMsg(what, 'Unexpected error: ' + err));
  800. assert.deepEqual(buf, data_, makeMsg(what, 'data mismatch'));
  801. });
  802. };
  803. },
  804. what: 'readFile (no size from fstat)'
  805. },
  806. { run: function() {
  807. setup(this);
  808. var self = this;
  809. var what = this.what;
  810. var client = this.client;
  811. var server = this.server;
  812. this.onReady = function() {
  813. var opens = 0;
  814. var reads = 0;
  815. var closes = 0;
  816. var path_ = '/foo/bar/baz';
  817. var handle_ = Buffer.from('hi mom!');
  818. var data_ = Buffer.from('hello world');
  819. server.on('OPEN', function(id, path, pflags, attrs) {
  820. assert(++opens === 1, makeMsg(what, 'Saw too many OPENs'));
  821. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  822. assert(path === path_, makeMsg(what, 'Wrong path: ' + path));
  823. assert(pflags === OPEN_MODE.READ,
  824. makeMsg(what, 'Wrong flags: ' + flagsToHuman(pflags)));
  825. server.handle(id, handle_);
  826. }).on('READ', function(id, handle, offset, len) {
  827. assert(++reads <= 2, makeMsg(what, 'Saw too many READs'));
  828. assert(id === reads, makeMsg(what, 'Wrong request id: ' + id));
  829. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  830. if (reads === 1) {
  831. assert(offset === 0, makeMsg(what, 'Wrong read offset: ' + offset));
  832. server.data(id, data_);
  833. } else
  834. server.status(id, STATUS_CODE.EOF);
  835. }).on('CLOSE', function(id, handle) {
  836. ++self.state.requests;
  837. assert(++closes === 1, makeMsg(what, 'Saw too many CLOSEs'));
  838. assert(id === 3, makeMsg(what, 'Wrong request id: ' + id));
  839. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  840. server.status(id, STATUS_CODE.OK);
  841. server.end();
  842. });
  843. var buf = [];
  844. client.createReadStream(path_).on('readable', function() {
  845. var chunk;
  846. while ((chunk = this.read()) !== null) {
  847. buf.push(chunk);
  848. }
  849. }).on('end', function() {
  850. assert(++self.state.responses === 1,
  851. makeMsg(what, 'Saw too many responses'));
  852. buf = Buffer.concat(buf);
  853. assert.deepEqual(buf, data_, makeMsg(what, 'data mismatch'));
  854. });
  855. };
  856. },
  857. what: 'ReadStream'
  858. },
  859. { run: function() {
  860. setup(this);
  861. var self = this;
  862. var what = this.what;
  863. var client = this.client;
  864. var server = this.server;
  865. this.onReady = function() {
  866. var opens = 0;
  867. var path_ = '/foo/bar/baz';
  868. var error;
  869. server.on('OPEN', function(id, path, pflags, attrs) {
  870. ++opens;
  871. ++self.state.requests;
  872. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  873. assert(path === path_, makeMsg(what, 'Wrong path: ' + path));
  874. assert(pflags === OPEN_MODE.READ,
  875. makeMsg(what, 'Wrong flags: ' + flagsToHuman(pflags)));
  876. server.status(id, STATUS_CODE.NO_SUCH_FILE);
  877. server.end();
  878. });
  879. client.createReadStream(path_).on('error', function(err) {
  880. error = err;
  881. }).on('close', function() {
  882. assert(opens === 1, makeMsg(what, 'Saw ' + opens + ' OPENs'));
  883. assert(error, makeMsg(what, 'Expected error'));
  884. assert(++self.state.responses === 1,
  885. makeMsg(what, 'Saw too many responses'));
  886. });
  887. };
  888. },
  889. what: 'ReadStream (error)'
  890. },
  891. { run: function() {
  892. setup(this);
  893. var self = this;
  894. var what = this.what;
  895. var client = this.client;
  896. var server = this.server;
  897. this.onReady = function() {
  898. var opens = 0;
  899. var writes = 0;
  900. var closes = 0;
  901. var fsetstat = false;
  902. var path_ = '/foo/bar/baz';
  903. var handle_ = Buffer.from('hi mom!');
  904. var data_ = Buffer.from('hello world');
  905. var expFlags = OPEN_MODE.TRUNC | OPEN_MODE.CREAT | OPEN_MODE.WRITE;
  906. server.on('OPEN', function(id, path, pflags, attrs) {
  907. assert(++opens === 1, makeMsg(what, 'Saw too many OPENs'));
  908. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  909. assert(path === path_, makeMsg(what, 'Wrong path: ' + path));
  910. assert(pflags === expFlags,
  911. makeMsg(what, 'Wrong flags: ' + flagsToHuman(pflags)));
  912. server.handle(id, handle_);
  913. }).once('FSETSTAT', function(id, handle, attrs) {
  914. fsetstat = true;
  915. assert(id === 1, makeMsg(what, 'Wrong request id: ' + id));
  916. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  917. assert.strictEqual(attrs.mode,
  918. parseInt('0666', 8),
  919. makeMsg(what, 'Wrong file mode'));
  920. server.status(id, STATUS_CODE.OK);
  921. }).on('WRITE', function(id, handle, offset, data) {
  922. assert(++writes <= 3, makeMsg(what, 'Saw too many WRITEs'));
  923. assert(id === writes + 1, makeMsg(what, 'Wrong request id: ' + id));
  924. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  925. assert(offset === ((writes - 1) * data_.length),
  926. makeMsg(what, 'Wrong write offset: ' + offset));
  927. assert.deepEqual(data, data_, makeMsg(what, 'Wrong data'));
  928. server.status(id, STATUS_CODE.OK);
  929. }).on('CLOSE', function(id, handle) {
  930. ++self.state.requests;
  931. assert(++closes === 1, makeMsg(what, 'Saw too many CLOSEs'));
  932. assert(id === 5, makeMsg(what, 'Wrong request id: ' + id));
  933. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  934. server.status(id, STATUS_CODE.OK);
  935. server.end();
  936. }).on('end', function() {
  937. assert(++self.state.responses === 1,
  938. makeMsg(what, 'Saw too many responses'));
  939. assert(opens === 1, makeMsg(what, 'Wrong OPEN count'));
  940. assert(writes === 3, makeMsg(what, 'Wrong WRITE count'));
  941. assert(closes === 1, makeMsg(what, 'Wrong CLOSE count'));
  942. assert(fsetstat, makeMsg(what, 'Expected FSETSTAT'));
  943. });
  944. var writer = client.createWriteStream(path_);
  945. if (writer.cork)
  946. writer.cork();
  947. writer.write(data_);
  948. writer.write(data_);
  949. writer.write(data_);
  950. if (writer.uncork)
  951. writer.uncork();
  952. writer.end();
  953. };
  954. },
  955. what: 'WriteStream'
  956. },
  957. // other client request scenarios
  958. { run: function() {
  959. setup(this);
  960. var self = this;
  961. var what = this.what;
  962. var client = this.client;
  963. var server = this.server;
  964. this.onReady = function() {
  965. var handle_ = Buffer.from('node.js');
  966. server.on('READDIR', function(id, handle) {
  967. assert(++self.state.requests === 1,
  968. makeMsg(what, 'Saw too many requests'));
  969. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  970. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  971. server.status(id, STATUS_CODE.EOF);
  972. server.end();
  973. });
  974. client.readdir(handle_, function(err, list) {
  975. assert(++self.state.responses === 1,
  976. makeMsg(what, 'Saw too many responses'));
  977. assert(err && err.code === STATUS_CODE.EOF,
  978. makeMsg(what, 'Expected EOF, got: ' + err));
  979. });
  980. };
  981. },
  982. what: 'readdir (EOF)'
  983. },
  984. { run: function() {
  985. setup(this);
  986. var self = this;
  987. var what = this.what;
  988. var client = this.client;
  989. var server = this.server;
  990. this.onReady = function() {
  991. var path_ = '/tmp/foo.txt';
  992. var reqs = 0;
  993. var continues = 0;
  994. client.unpipe(server);
  995. function clientCb(err, handle) {
  996. assert(++self.state.responses <= reqs,
  997. makeMsg(what, 'Saw too many responses'));
  998. if (self.state.responses === reqs) {
  999. assert(continues === 1, makeMsg(what, 'no continue event seen'));
  1000. server.end();
  1001. }
  1002. }
  1003. client.on('continue', function() {
  1004. assert(++continues === 1, makeMsg(what, 'saw > 1 continue event'));
  1005. });
  1006. while (true) {
  1007. ++reqs;
  1008. if (!client.open(path_, 'w', clientCb))
  1009. break;
  1010. }
  1011. client.pipe(server);
  1012. };
  1013. },
  1014. expected: {
  1015. requests: -1,
  1016. responses: -1
  1017. },
  1018. what: '"continue" event after push() === false'
  1019. },
  1020. { run: function() {
  1021. var self = this;
  1022. var client = new SFTPStream();
  1023. client.once('ready', function() {
  1024. client.open('/foo/bar', 'w', function(err, handle) {
  1025. assert(err, 'Expected error');
  1026. assert.strictEqual(err.code, 4);
  1027. assert.strictEqual(err.message, 'Uh oh');
  1028. assert.strictEqual(err.lang, '');
  1029. next();
  1030. });
  1031. client.write(Buffer.from([
  1032. 0, 0, 0, 18,
  1033. 101,
  1034. 0, 0, 0, 0,
  1035. 0, 0, 0, SFTPStream.STATUS_CODE.FAILURE,
  1036. 0, 0, 0, 5, 85, 104, 32, 111, 104
  1037. ]));
  1038. });
  1039. client.write(Buffer.from([
  1040. 0, 0, 0, 5,
  1041. 2,
  1042. 0, 0, 0, 3
  1043. ]));
  1044. },
  1045. what: 'Can parse status response without language'
  1046. },
  1047. { run: function() {
  1048. var self = this;
  1049. var client = new SFTPStream();
  1050. client.once('ready', function() {
  1051. client.open('/foo/bar', 'w', function(err, handle) {
  1052. assert(err, 'Expected error');
  1053. assert.strictEqual(err.code, 4);
  1054. assert.strictEqual(err.message, 'Failure');
  1055. assert.strictEqual(err.lang, '');
  1056. next();
  1057. });
  1058. client.write(Buffer.from([
  1059. 0, 0, 0, 9,
  1060. 101,
  1061. 0, 0, 0, 0,
  1062. 0, 0, 0, SFTPStream.STATUS_CODE.FAILURE
  1063. ]));
  1064. });
  1065. client.write(Buffer.from([
  1066. 0, 0, 0, 5,
  1067. 2,
  1068. 0, 0, 0, 3
  1069. ]));
  1070. },
  1071. what: 'Can parse status response without message'
  1072. },
  1073. { run: function() {
  1074. var self = this;
  1075. var err;
  1076. var client = new SFTPStream();
  1077. client.once('ready', function() {
  1078. assert(false, 'Handshake should not succeed');
  1079. }).once('error', function(err_) {
  1080. err = err_;
  1081. }).once('end', function() {
  1082. assert.strictEqual(err && err.message,
  1083. 'Unexpected packet before version');
  1084. next();
  1085. });
  1086. client.write(Buffer.from([
  1087. 1, 2, 3, 4,
  1088. 5,
  1089. 6, 7, 8, 9
  1090. ]));
  1091. },
  1092. what: 'End SFTP stream on bad handshake (client)'
  1093. },
  1094. { run: function() {
  1095. var self = this;
  1096. var err;
  1097. var client = new SFTPStream({ server: true });
  1098. client.once('ready', function() {
  1099. assert(false, 'Handshake should not succeed');
  1100. }).once('error', function(err_) {
  1101. err = err_;
  1102. }).once('end', function() {
  1103. assert.strictEqual(err && err.message,
  1104. 'Unexpected packet before init');
  1105. next();
  1106. });
  1107. client.write(Buffer.from([
  1108. 1, 2, 3, 4,
  1109. 5,
  1110. 6, 7, 8, 9
  1111. ]));
  1112. },
  1113. what: 'End SFTP stream on bad handshake (server)'
  1114. },
  1115. { run: function() {
  1116. setup(this);
  1117. var self = this;
  1118. var what = this.what;
  1119. var client = this.client;
  1120. var server = this.server;
  1121. this.onReady = function() {
  1122. var handle_ = Buffer.from([0,0,0,1]);
  1123. var buffer = Buffer.allocUnsafe(4);
  1124. server.once('READ', function(id, handle, offset, len) {
  1125. ++self.state.requests;
  1126. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  1127. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  1128. assert(offset === 0, makeMsg(what, 'Wrong read offset: ' + offset));
  1129. assert(len === buffer.length,
  1130. makeMsg(what, 'Wrong read length: ' + len));
  1131. server.data(id, Buffer.alloc(len + 1));
  1132. });
  1133. client.readData(handle_, buffer, 0, buffer.length, 0, clientReadCb);
  1134. function clientReadCb(err, buf) {
  1135. ++self.state.responses;
  1136. assert(err && err.message.indexOf('more data than requested') !== -1,
  1137. makeMsg(what, 'Expected error'));
  1138. server.end();
  1139. }
  1140. };
  1141. },
  1142. what: 'Abort on data chunk larger than requested'
  1143. },
  1144. ];
  1145. function setup(self) {
  1146. var expectedRequests = (self.expected && self.expected.requests) || 1;
  1147. var expectedResponses = (self.expected && self.expected.responses) || 1;
  1148. var clientEnded = false;
  1149. var serverEnded = false;
  1150. self.state = {
  1151. clientReady: false,
  1152. serverReady: false,
  1153. requests: 0,
  1154. responses: 0
  1155. };
  1156. self.client = new SFTPStream();
  1157. self.server = new SFTPStream({ server: true });
  1158. self.server.on('error', onError)
  1159. .on('ready', onReady)
  1160. .on('end', onEnd);
  1161. self.client.on('error', onError)
  1162. .on('ready', onReady)
  1163. .on('end', onEnd);
  1164. function onError(err) {
  1165. var which = (this === self.server ? 'server' : 'client');
  1166. assert(false, makeMsg(self.what, 'Unexpected ' + which + ' error: ' + err));
  1167. }
  1168. function onReady() {
  1169. if (this === self.client) {
  1170. assert(!self.state.clientReady,
  1171. makeMsg(self.what, 'Received multiple ready events for client'));
  1172. self.state.clientReady = true;
  1173. } else {
  1174. assert(!self.state.serverReady,
  1175. makeMsg(self.what, 'Received multiple ready events for server'));
  1176. self.state.serverReady = true;
  1177. }
  1178. if (self.state.clientReady && self.state.serverReady)
  1179. self.onReady && self.onReady();
  1180. }
  1181. function onEnd() {
  1182. if (this === self.client) {
  1183. assert(!clientEnded,
  1184. makeMsg(self.what, 'Received multiple close events for client'));
  1185. clientEnded = true;
  1186. } else {
  1187. assert(!serverEnded,
  1188. makeMsg(self.what, 'Received multiple close events for server'));
  1189. serverEnded = true;
  1190. }
  1191. if (clientEnded && serverEnded) {
  1192. var msg;
  1193. if (expectedRequests > 0) {
  1194. msg = 'Expected ' + expectedRequests + ' request(s) but received '
  1195. + self.state.requests;
  1196. assert(self.state.requests === expectedRequests,
  1197. makeMsg(self.what, msg));
  1198. }
  1199. if (expectedResponses > 0) {
  1200. msg = 'Expected ' + expectedResponses + ' response(s) but received '
  1201. + self.state.responses;
  1202. assert(self.state.responses === expectedResponses,
  1203. makeMsg(self.what, msg));
  1204. }
  1205. next();
  1206. }
  1207. }
  1208. process.nextTick(function() {
  1209. self.client.pipe(self.server).pipe(self.client);
  1210. });
  1211. }
  1212. function flagsToHuman(flags) {
  1213. var ret = [];
  1214. for (var i = 0, keys = Object.keys(OPEN_MODE); i < keys.length; ++i)
  1215. if (flags & OPEN_MODE[keys[i]])
  1216. ret.push(keys[i]);
  1217. return ret.join(' | ');
  1218. }
  1219. function next() {
  1220. if (++t === tests.length)
  1221. return;
  1222. var v = tests[t];
  1223. v.run.call(v);
  1224. }
  1225. function makeMsg(what, msg) {
  1226. return '[' + group + what + ']: ' + msg;
  1227. }
  1228. process.once('exit', function() {
  1229. assert(t === tests.length,
  1230. makeMsg('_exit',
  1231. 'Only finished ' + t + '/' + tests.length + ' tests'));
  1232. });
  1233. next();