Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

test-sftp.js 46KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383
  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 path_ = '/foo/bar/baz';
  867. var handle_ = Buffer.from('hi mom!');
  868. var data_ = Buffer.from('hello world');
  869. server.on('OPEN', function(id, path, pflags, attrs) {
  870. server.handle(id, handle_);
  871. }).on('READ', function(id, handle, offset, len) {
  872. if (offset > data_.length) {
  873. server.status(id, STATUS_CODE.EOF);
  874. } else {
  875. // Only read 4 bytes at a time
  876. server.data(id, data_.slice(offset, offset + 4));
  877. }
  878. }).on('CLOSE', function(id, handle) {
  879. ++self.state.requests;
  880. server.status(id, STATUS_CODE.OK);
  881. server.end();
  882. });
  883. var buf = [];
  884. client.createReadStream(path_).on('readable', function() {
  885. var chunk;
  886. while ((chunk = this.read()) !== null) {
  887. buf.push(chunk);
  888. }
  889. }).on('end', function() {
  890. self.state.responses += 1;
  891. buf = Buffer.concat(buf);
  892. assert.deepEqual(buf, data_, makeMsg(what, 'data mismatch'));
  893. });
  894. };
  895. },
  896. what: 'ReadStream (fewer bytes than requested)'
  897. },
  898. { run: function() {
  899. setup(this);
  900. var self = this;
  901. var what = this.what;
  902. var client = this.client;
  903. var server = this.server;
  904. this.onReady = function() {
  905. var opens = 0;
  906. var path_ = '/foo/bar/baz';
  907. var error;
  908. server.on('OPEN', function(id, path, pflags, attrs) {
  909. ++opens;
  910. ++self.state.requests;
  911. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  912. assert(path === path_, makeMsg(what, 'Wrong path: ' + path));
  913. assert(pflags === OPEN_MODE.READ,
  914. makeMsg(what, 'Wrong flags: ' + flagsToHuman(pflags)));
  915. server.status(id, STATUS_CODE.NO_SUCH_FILE);
  916. server.end();
  917. });
  918. client.createReadStream(path_).on('error', function(err) {
  919. error = err;
  920. }).on('close', function() {
  921. assert(opens === 1, makeMsg(what, 'Saw ' + opens + ' OPENs'));
  922. assert(error, makeMsg(what, 'Expected error'));
  923. assert(++self.state.responses === 1,
  924. makeMsg(what, 'Saw too many responses'));
  925. });
  926. };
  927. },
  928. what: 'ReadStream (error)'
  929. },
  930. { run: function() {
  931. setup(this);
  932. var self = this;
  933. var what = this.what;
  934. var client = this.client;
  935. var server = this.server;
  936. this.onReady = function() {
  937. var opens = 0;
  938. var writes = 0;
  939. var closes = 0;
  940. var fsetstat = false;
  941. var path_ = '/foo/bar/baz';
  942. var handle_ = Buffer.from('hi mom!');
  943. var data_ = Buffer.from('hello world');
  944. var expFlags = OPEN_MODE.TRUNC | OPEN_MODE.CREAT | OPEN_MODE.WRITE;
  945. server.on('OPEN', function(id, path, pflags, attrs) {
  946. assert(++opens === 1, makeMsg(what, 'Saw too many OPENs'));
  947. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  948. assert(path === path_, makeMsg(what, 'Wrong path: ' + path));
  949. assert(pflags === expFlags,
  950. makeMsg(what, 'Wrong flags: ' + flagsToHuman(pflags)));
  951. server.handle(id, handle_);
  952. }).once('FSETSTAT', function(id, handle, attrs) {
  953. fsetstat = true;
  954. assert(id === 1, makeMsg(what, 'Wrong request id: ' + id));
  955. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  956. assert.strictEqual(attrs.mode,
  957. parseInt('0666', 8),
  958. makeMsg(what, 'Wrong file mode'));
  959. server.status(id, STATUS_CODE.OK);
  960. }).on('WRITE', function(id, handle, offset, data) {
  961. assert(++writes <= 3, makeMsg(what, 'Saw too many WRITEs'));
  962. assert(id === writes + 1, makeMsg(what, 'Wrong request id: ' + id));
  963. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  964. assert(offset === ((writes - 1) * data_.length),
  965. makeMsg(what, 'Wrong write offset: ' + offset));
  966. assert.deepEqual(data, data_, makeMsg(what, 'Wrong data'));
  967. server.status(id, STATUS_CODE.OK);
  968. }).on('CLOSE', function(id, handle) {
  969. ++self.state.requests;
  970. assert(++closes === 1, makeMsg(what, 'Saw too many CLOSEs'));
  971. assert(id === 5, makeMsg(what, 'Wrong request id: ' + id));
  972. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  973. server.status(id, STATUS_CODE.OK);
  974. server.end();
  975. }).on('end', function() {
  976. assert(++self.state.responses === 1,
  977. makeMsg(what, 'Saw too many responses'));
  978. assert(opens === 1, makeMsg(what, 'Wrong OPEN count'));
  979. assert(writes === 3, makeMsg(what, 'Wrong WRITE count'));
  980. assert(closes === 1, makeMsg(what, 'Wrong CLOSE count'));
  981. assert(fsetstat, makeMsg(what, 'Expected FSETSTAT'));
  982. });
  983. var writer = client.createWriteStream(path_);
  984. if (writer.cork)
  985. writer.cork();
  986. writer.write(data_);
  987. writer.write(data_);
  988. writer.write(data_);
  989. if (writer.uncork)
  990. writer.uncork();
  991. writer.end();
  992. };
  993. },
  994. what: 'WriteStream'
  995. },
  996. // other client request scenarios
  997. { run: function() {
  998. setup(this);
  999. var self = this;
  1000. var what = this.what;
  1001. var client = this.client;
  1002. var server = this.server;
  1003. this.onReady = function() {
  1004. var handle_ = Buffer.from('node.js');
  1005. server.on('READDIR', function(id, handle) {
  1006. assert(++self.state.requests === 1,
  1007. makeMsg(what, 'Saw too many requests'));
  1008. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  1009. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  1010. server.status(id, STATUS_CODE.EOF);
  1011. server.end();
  1012. });
  1013. client.readdir(handle_, function(err, list) {
  1014. assert(++self.state.responses === 1,
  1015. makeMsg(what, 'Saw too many responses'));
  1016. assert(err && err.code === STATUS_CODE.EOF,
  1017. makeMsg(what, 'Expected EOF, got: ' + err));
  1018. });
  1019. };
  1020. },
  1021. what: 'readdir (EOF)'
  1022. },
  1023. { run: function() {
  1024. setup(this);
  1025. var self = this;
  1026. var what = this.what;
  1027. var client = this.client;
  1028. var server = this.server;
  1029. this.onReady = function() {
  1030. var path_ = '/tmp/foo.txt';
  1031. var reqs = 0;
  1032. var continues = 0;
  1033. client.unpipe(server);
  1034. function clientCb(err, handle) {
  1035. assert(++self.state.responses <= reqs,
  1036. makeMsg(what, 'Saw too many responses'));
  1037. if (self.state.responses === reqs) {
  1038. assert(continues === 1, makeMsg(what, 'no continue event seen'));
  1039. server.end();
  1040. }
  1041. }
  1042. client.on('continue', function() {
  1043. assert(++continues === 1, makeMsg(what, 'saw > 1 continue event'));
  1044. });
  1045. while (true) {
  1046. ++reqs;
  1047. if (!client.open(path_, 'w', clientCb))
  1048. break;
  1049. }
  1050. client.pipe(server);
  1051. };
  1052. },
  1053. expected: {
  1054. requests: -1,
  1055. responses: -1
  1056. },
  1057. what: '"continue" event after push() === false'
  1058. },
  1059. { run: function() {
  1060. var self = this;
  1061. var client = new SFTPStream();
  1062. client.once('ready', function() {
  1063. client.open('/foo/bar', 'w', function(err, handle) {
  1064. assert(err, 'Expected error');
  1065. assert.strictEqual(err.code, 4);
  1066. assert.strictEqual(err.message, 'Uh oh');
  1067. assert.strictEqual(err.lang, '');
  1068. next();
  1069. });
  1070. client.write(Buffer.from([
  1071. 0, 0, 0, 18,
  1072. 101,
  1073. 0, 0, 0, 0,
  1074. 0, 0, 0, SFTPStream.STATUS_CODE.FAILURE,
  1075. 0, 0, 0, 5, 85, 104, 32, 111, 104
  1076. ]));
  1077. });
  1078. client.write(Buffer.from([
  1079. 0, 0, 0, 5,
  1080. 2,
  1081. 0, 0, 0, 3
  1082. ]));
  1083. },
  1084. what: 'Can parse status response without language'
  1085. },
  1086. { run: function() {
  1087. var self = this;
  1088. var client = new SFTPStream();
  1089. client.once('ready', function() {
  1090. client.open('/foo/bar', 'w', function(err, handle) {
  1091. assert(err, 'Expected error');
  1092. assert.strictEqual(err.code, 4);
  1093. assert.strictEqual(err.message, 'Failure');
  1094. assert.strictEqual(err.lang, '');
  1095. next();
  1096. });
  1097. client.write(Buffer.from([
  1098. 0, 0, 0, 9,
  1099. 101,
  1100. 0, 0, 0, 0,
  1101. 0, 0, 0, SFTPStream.STATUS_CODE.FAILURE
  1102. ]));
  1103. });
  1104. client.write(Buffer.from([
  1105. 0, 0, 0, 5,
  1106. 2,
  1107. 0, 0, 0, 3
  1108. ]));
  1109. },
  1110. what: 'Can parse status response without message'
  1111. },
  1112. { run: function() {
  1113. var self = this;
  1114. var err;
  1115. var client = new SFTPStream();
  1116. client.once('ready', function() {
  1117. assert(false, 'Handshake should not succeed');
  1118. }).once('error', function(err_) {
  1119. err = err_;
  1120. }).once('end', function() {
  1121. assert.strictEqual(err && err.message,
  1122. 'Unexpected packet before version');
  1123. next();
  1124. });
  1125. client.write(Buffer.from([
  1126. 1, 2, 3, 4,
  1127. 5,
  1128. 6, 7, 8, 9
  1129. ]));
  1130. },
  1131. what: 'End SFTP stream on bad handshake (client)'
  1132. },
  1133. { run: function() {
  1134. var self = this;
  1135. var err;
  1136. var client = new SFTPStream({ server: true });
  1137. client.once('ready', function() {
  1138. assert(false, 'Handshake should not succeed');
  1139. }).once('error', function(err_) {
  1140. err = err_;
  1141. }).once('end', function() {
  1142. assert.strictEqual(err && err.message,
  1143. 'Unexpected packet before init');
  1144. next();
  1145. });
  1146. client.write(Buffer.from([
  1147. 1, 2, 3, 4,
  1148. 5,
  1149. 6, 7, 8, 9
  1150. ]));
  1151. },
  1152. what: 'End SFTP stream on bad handshake (server)'
  1153. },
  1154. { run: function() {
  1155. setup(this);
  1156. var self = this;
  1157. var what = this.what;
  1158. var client = this.client;
  1159. var server = this.server;
  1160. this.onReady = function() {
  1161. var handle_ = Buffer.from([0,0,0,1]);
  1162. var buffer = Buffer.allocUnsafe(4);
  1163. server.once('READ', function(id, handle, offset, len) {
  1164. ++self.state.requests;
  1165. assert(id === 0, makeMsg(what, 'Wrong request id: ' + id));
  1166. assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch'));
  1167. assert(offset === 0, makeMsg(what, 'Wrong read offset: ' + offset));
  1168. assert(len === buffer.length,
  1169. makeMsg(what, 'Wrong read length: ' + len));
  1170. server.data(id, Buffer.alloc(len + 1));
  1171. });
  1172. client.readData(handle_, buffer, 0, buffer.length, 0, clientReadCb);
  1173. function clientReadCb(err, buf) {
  1174. ++self.state.responses;
  1175. assert(err && err.message.indexOf('more data than requested') !== -1,
  1176. makeMsg(what, 'Expected error'));
  1177. server.end();
  1178. }
  1179. };
  1180. },
  1181. what: 'Abort on data chunk larger than requested'
  1182. },
  1183. { run: function() {
  1184. setup(this);
  1185. var self = this;
  1186. var what = this.what;
  1187. var client = this.client;
  1188. client._state.extensions['statvfs@openssh.com'] = ['2'];
  1189. this.onReady = function() {
  1190. var pathOne_ = '/foo/baz';
  1191. client.ext_openssh_statvfs(pathOne_, function(err, fsInfo) {
  1192. assert(++self.state.responses === 1,
  1193. makeMsg(what, 'Saw too many responses'));
  1194. assert(err && err.code === STATUS_CODE.OP_UNSUPPORTED,
  1195. makeMsg(what, 'Expected OP_UNSUPPORTED, got: ' + err));
  1196. var pathTwo_ = '/baz/foo';
  1197. client.ext_openssh_statvfs(pathTwo_, function(err, fsInfo) {
  1198. assert(++self.state.responses === 2,
  1199. makeMsg(what, 'Saw too many responses'));
  1200. assert(err && err.code === STATUS_CODE.OP_UNSUPPORTED,
  1201. makeMsg(what, 'Expected OP_UNSUPPORTED, got: ' + err));
  1202. next();
  1203. });
  1204. });
  1205. };
  1206. },
  1207. what: 'Multiple extended operations in sequence fail as expected'
  1208. },
  1209. ];
  1210. function setup(self) {
  1211. var expectedRequests = (self.expected && self.expected.requests) || 1;
  1212. var expectedResponses = (self.expected && self.expected.responses) || 1;
  1213. var clientEnded = false;
  1214. var serverEnded = false;
  1215. self.state = {
  1216. clientReady: false,
  1217. serverReady: false,
  1218. requests: 0,
  1219. responses: 0
  1220. };
  1221. self.client = new SFTPStream();
  1222. self.server = new SFTPStream({ server: true });
  1223. self.server.on('error', onError)
  1224. .on('ready', onReady)
  1225. .on('end', onEnd);
  1226. self.client.on('error', onError)
  1227. .on('ready', onReady)
  1228. .on('end', onEnd);
  1229. function onError(err) {
  1230. var which = (this === self.server ? 'server' : 'client');
  1231. assert(false, makeMsg(self.what, 'Unexpected ' + which + ' error: ' + err));
  1232. }
  1233. function onReady() {
  1234. if (this === self.client) {
  1235. assert(!self.state.clientReady,
  1236. makeMsg(self.what, 'Received multiple ready events for client'));
  1237. self.state.clientReady = true;
  1238. } else {
  1239. assert(!self.state.serverReady,
  1240. makeMsg(self.what, 'Received multiple ready events for server'));
  1241. self.state.serverReady = true;
  1242. }
  1243. if (self.state.clientReady && self.state.serverReady)
  1244. self.onReady && self.onReady();
  1245. }
  1246. function onEnd() {
  1247. if (this === self.client) {
  1248. assert(!clientEnded,
  1249. makeMsg(self.what, 'Received multiple close events for client'));
  1250. clientEnded = true;
  1251. } else {
  1252. assert(!serverEnded,
  1253. makeMsg(self.what, 'Received multiple close events for server'));
  1254. serverEnded = true;
  1255. }
  1256. if (clientEnded && serverEnded) {
  1257. var msg;
  1258. if (expectedRequests > 0) {
  1259. msg = 'Expected ' + expectedRequests + ' request(s) but received '
  1260. + self.state.requests;
  1261. assert(self.state.requests === expectedRequests,
  1262. makeMsg(self.what, msg));
  1263. }
  1264. if (expectedResponses > 0) {
  1265. msg = 'Expected ' + expectedResponses + ' response(s) but received '
  1266. + self.state.responses;
  1267. assert(self.state.responses === expectedResponses,
  1268. makeMsg(self.what, msg));
  1269. }
  1270. next();
  1271. }
  1272. }
  1273. process.nextTick(function() {
  1274. self.client.pipe(self.server).pipe(self.client);
  1275. });
  1276. }
  1277. function flagsToHuman(flags) {
  1278. var ret = [];
  1279. for (var i = 0, keys = Object.keys(OPEN_MODE); i < keys.length; ++i)
  1280. if (flags & OPEN_MODE[keys[i]])
  1281. ret.push(keys[i]);
  1282. return ret.join(' | ');
  1283. }
  1284. function next() {
  1285. if (++t === tests.length)
  1286. return;
  1287. var v = tests[t];
  1288. v.run.call(v);
  1289. }
  1290. function makeMsg(what, msg) {
  1291. return '[' + group + what + ']: ' + msg;
  1292. }
  1293. process.once('exit', function() {
  1294. assert(t === tests.length,
  1295. makeMsg('_exit',
  1296. 'Only finished ' + t + '/' + tests.length + ' tests'));
  1297. });
  1298. next();