moll / node-mitm

Intercept and mock outgoing Node.js network TCP connections and HTTP requests for testing. Intercepts and gives you a Net.Socket, Http.IncomingMessage and Http.ServerResponse to test and respond with. Super useful when testing code that hits remote servers.
Other
637 stars 48 forks source link

Mitm v1.4.0 not working in Node v8.9.4 #53

Closed earllapura closed 5 years ago

earllapura commented 5 years ago

I tried to use net to mock a socket and i found out that it was not intercepting. I have Node v8.9.4 and mitm v1.4.0 . My package.json has

    "dependencies": {
        "modem": "^1.0.3",
        "serialport": "^6.0"
    },
    "devDependencies": {
        "chai": "^4.2.0",
        "mitm": "^1.4.0",
        "mocha": "^5.2.0",
        "sinon": "^6.3.5"
    },
    "scripts": {
        "test": "mocha"
    }

I ran the tests in the mitm folder in ./node_modules and the results are:

$ npm test ./node_modules/mitm/test/index_test.js

> @ test C:\Users\Developer\Desktop\SASE-globe
> mocha "./node_modules/mitm/test/index_test.js"

  Mitm
    $ npm test ./node_modules/mitm/test/index_test.js

> @ test C:\myproject
> mocha "./node_modules/mitm/test/index_test.js"

  Mitm
    1) must return an instance of Mitm when called as a function
    Net.connect
      2) must not return an instance of Tls.TLSSocket
      3) must not set the encrypted property
      4) must not set the authorized property
      √ must not emit secureConnect on client
      √ must not emit secureConnect on server
      as connect
        5) must return an instance of Net.Socket
        6) must return an instance of Net.Socket given port
        7) must return an instance of Net.Socket given port and host
        8) must emit connect on Mitm
        9) must emit connect on Mitm with options object given host and port
        10) must emit connection on Mitm
        √ must emit connect on socket in next ticks
        √ must call back on connect given callback
        √ must call back on connect given port and callback
        √ must call back on connect given port, host and callback
        11) must intercept 127.0.0.1
        when bypassed
`sandbox.create()` is deprecated. Use default sandbox at `sinon.sandbox` or create new sandboxes with `sinon.createSandbox()`
          12) must not intercept
`sandbox.create()` is deprecated. Use default sandbox at `sinon.sandbox` or create new sandboxes with `sinon.createSandbox()`
          13) must call original module.connect
`sandbox.create()` is deprecated. Use default sandbox at `sinon.sandbox` or create new sandboxes with `sinon.createSandbox()`
          14) must not call back twice on connect given callback
`sandbox.create()` is deprecated. Use default sandbox at `sinon.sandbox` or create new sandboxes with `sinon.createSandbox()`
          15) must not emit connection
      Socket
        .prototype.write
          16) must write to client from server
          17) must write to client from server in the next tick
          18) must write to server from client
          √ must write to server from client
          19) must write to server from client given binary
          √ must write to server from client given binary
          20) must write to server from client given binary

  8 passing (4s)
  20 failing

  1) Mitm
       must return an instance of Mitm when called as a function:
     TypeError: Cannot read property 'be' of undefined
      at Context.<anonymous> (node_modules\mitm\test\index_test.js:21:15)

  2) Mitm
       Net.connect
         must not return an instance of Tls.TLSSocket:
     TypeError: Cannot read property 'not' of undefined
      at Context.<anonymous> (node_modules\mitm\test\index_test.js:170:19)

  3) Mitm
       Net.connect
         must not set the encrypted property:
     TypeError: Cannot read property 'not' of undefined
      at Context.<anonymous> (node_modules\mitm\test\index_test.js:174:38)

  4) Mitm
       Net.connect
         must not set the authorized property:
     TypeError: Cannot read property 'not' of undefined
      at Context.<anonymous> (node_modules\mitm\test\index_test.js:178:38)

  5) Mitm
       Net.connect
         as connect
           must return an instance of Net.Socket:
     TypeError: Cannot read property 'be' of undefined
      at Context.<anonymous> (node_modules\mitm\test\index_test.js:29:21)

  6) Mitm
       Net.connect
         as connect
           must return an instance of Net.Socket given port:
     TypeError: Cannot read property 'be' of undefined
      at Context.<anonymous> (node_modules\mitm\test\index_test.js:33:32)

  7) Mitm
       Net.connect
         as connect
           must return an instance of Net.Socket given port and host:
     TypeError: Cannot read property 'be' of undefined
      at Context.<anonymous> (node_modules\mitm\test\index_test.js:38:44)

  8) Mitm
       Net.connect
         as connect
           must emit connect on Mitm:
     TypeError: Cannot read property 'equal' of undefined
      at Context.<anonymous> (node_modules\mitm\test\index_test.js:47:34)

  9) Mitm
       Net.connect
         as connect
           must emit connect on Mitm with options object given host and port:
     TypeError: Cannot read property 'equal' of undefined
      at Context.<anonymous> (node_modules\mitm\test\index_test.js:58:34)

  10) Mitm
       Net.connect
         as connect
           must emit connection on Mitm:
     TypeError: Cannot read property 'equal' of undefined
      at Context.<anonymous> (node_modules\mitm\test\index_test.js:69:37)

  11) Mitm
       Net.connect
         as connect
           must intercept 127.0.0.1:
     Uncaught TypeError: Cannot read property 'equal' of undefined
      at Socket.<anonymous> (node_modules\mitm\test\index_test.js:102:54)
      at addChunk (_stream_readable.js:263:12)
      at readableAddChunk (_stream_readable.js:246:13)
      at Socket.Readable.push (_stream_readable.js:208:10)
      at InternalSocket.onread (net.js:594:20)
      at InternalSocket.readData (node_modules\mitm\lib\internal_socket.js:125:13)
      at addChunk (_stream_readable.js:263:12)
      at readableAddChunk (_stream_readable.js:250:11)
      at InternalSocket.Readable.push (_stream_readable.js:208:10)
      at C:\myproject\node_modules\mitm\lib\internal_socket.js:58:40
      at _combinedTickCallback (internal/process/next_tick.js:131:7)
      at process._tickCallback (internal/process/next_tick.js:180:9)

  12) Mitm
       Net.connect
         as connect
           when bypassed
             must not intercept:
     Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (C:\myproject\node_modules\mitm\test\index_test.js)

  13) Mitm
       Net.connect
         as connect
           when bypassed
             must call original module.connect:
     TypeError: Cannot read property 'equal' of undefined
      at Context.<anonymous> (node_modules\mitm\test\index_test.js:129:36)

  14) Mitm
       Net.connect
         as connect
           when bypassed
             must not call back twice on connect given callback:
     Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (C:\myproject\node_modules\mitm\test\index_test.js)

  15) Mitm
       Net.connect
         as connect
           when bypassed
             must not emit connection:
     TypeError: Cannot read property 'equal' of undefined
      at Context.<anonymous> (node_modules\mitm\test\index_test.js:155:39)

  16) Mitm
       Net.connect
         Socket
           .prototype.write
             must write to client from server:
     Uncaught TypeError: Cannot read property 'equal' of undefined
      at Socket.<anonymous> (node_modules\mitm\test\index_test.js:204:56)
      at addChunk (_stream_readable.js:263:12)
      at readableAddChunk (_stream_readable.js:246:13)
      at Socket.Readable.push (_stream_readable.js:208:10)
      at InternalSocket.onread (net.js:594:20)
      at InternalSocket.readData (node_modules\mitm\lib\internal_socket.js:125:13)
      at addChunk (_stream_readable.js:263:12)
      at readableAddChunk (_stream_readable.js:250:11)
      at InternalSocket.Readable.push (_stream_readable.js:208:10)
      at C:\myproject\node_modules\mitm\lib\internal_socket.js:58:40
      at _combinedTickCallback (internal/process/next_tick.js:131:7)
      at process._tickCallback (internal/process/next_tick.js:180:9)

  17) Mitm
       Net.connect
         Socket
           .prototype.write
             must write to client from server in the next tick:
     Uncaught TypeError: Cannot read property 'be' of undefined
      at Socket.<anonymous> (node_modules\mitm\test\index_test.js:213:56)
      at addChunk (_stream_readable.js:263:12)
      at readableAddChunk (_stream_readable.js:250:11)
      at Socket.Readable.push (_stream_readable.js:208:10)
      at InternalSocket.onread (net.js:594:20)
      at InternalSocket.readData (node_modules\mitm\lib\internal_socket.js:125:13)
      at addChunk (_stream_readable.js:263:12)
      at readableAddChunk (_stream_readable.js:250:11)
      at InternalSocket.Readable.push (_stream_readable.js:208:10)
      at C:\myproject\node_modules\mitm\lib\internal_socket.js:58:40
      at _combinedTickCallback (internal/process/next_tick.js:131:7)
      at process._tickCallback (internal/process/next_tick.js:180:9)

  18) Mitm
       Net.connect
         Socket
           .prototype.write
             must write to server from client:
     Uncaught TypeError: Cannot read property 'equal' of undefined
      at C:\myproject\node_modules\mitm\test\index_test.js:224:59
      at _combinedTickCallback (internal/process/next_tick.js:131:7)
      at process._tickCallback (internal/process/next_tick.js:180:9)

  19) Mitm
       Net.connect
         Socket
           .prototype.write
             must write to server from client given binary:
     Uncaught TypeError: Cannot read property 'equal' of undefined
      at C:\myproject\node_modules\mitm\test\index_test.js:246:59
      at _combinedTickCallback (internal/process/next_tick.js:131:7)
      at Immediate._tickCallback [as _onImmediate] (internal/process/next_tick.js:180:9)

  20) Mitm
       Net.connect
         Socket
           .prototype.write
             must write to server from client given binary:
     Uncaught TypeError: Cannot read property 'equal' of undefined
      at C:\myproject\node_modules\mitm\test\index_test.js:246:59
      at _combinedTickCallback (internal/process/next_tick.js:131:7)
      at Immediate._tickCallback [as _onImmediate] (internal/process/next_tick.js:180:9)

          √ must write to server from client given binary
npm ERR! Test failed.  See above for more details.

What happened?

moll commented 5 years ago

Hey,

So, we've got two problems: One is failing to intercept in your own code and failing Mitm.js's tests. When you ran Mitm.js's, did you install its [development] dependencies, too? It kind of reads like Node is loading your own app's dependencies.

Secondly, do you have a small example of code from your own tests that's failing that led you to create this issue in the first place?

earllapura commented 5 years ago

Thanks for replying.

Yes, when I cloned your repository and ran the test (I changed the package.json a bit to make it run using mocha), it passed except those of callback delays, which is irrelevant to my bug. The bug is that the mock socket does not return the expected value.

This is the error message:

$ npm test

> @ test C:\my-project
> mocha

  SmsServerBridge
null
    1) shouldConnectToServer

  0 passing (15ms)
  1 failing

  1) SmsServerBridge
       shouldConnectToServer:
     TypeError: Cannot read property 'should' of null
      at Context.<anonymous> (test\SmsServerBridgeTest.js:23:22)

The test file is:

const should = require('chai').should();

var server = require('../lib/SmsServerBridge');
const net = require('net');

describe('SmsServerBridge', function() {
    var Mitm = require('mitm'), mitm;
    beforeEach(function(){
        mitm = Mitm();
    });
    afterEach(function(){
        mitm.disable();
    });

    it('shouldConnectToServer', function(){
        mitm.on("connection", function(socket) { socket.write("Hello back!") });
        var socket = net.connect(22, "example.org");
        // var serverIn = server(socket, {device: {name: "device"}});
        socket.write("hello");
        socket.setEncoding("utf8")
        console.log(socket.read());
        socket.read().should.equal({device:'hello'});
    });
});
moll commented 5 years ago

Ah, I think the issue could be that socket.read only returns data in either the next tick or when it fires the data event:

process.nextTick(function() { console.log(socket.read()) })
// Or
socket.on("data", console.log)

I see my examples in README assume pure synchrony. That worked with earlier Node versions, but somewhere around maybe v6 or v8 it changed to requiring a tick or more. I'll update the README immediately!

Yes, when I cloned your repository and ran the test (I changed the package.json a bit to make it run using mocha),

How come? Does Make not run on your system?

I don't particularly want those tests to remain failing either. You don't happen to have another Node version around to try, do you? Travis CI tests Mitm.js on v8.11 and v8.11 and those work. I wonder if it's something in v8.9.4...

earllapura commented 5 years ago

@moll Thank you. It worked now. That is so dumb of me to forget that the whole thing is async.

How come? Does Make not run on your system?

I used Git for Windows Bash, with added make utility. For some reason _mocha in node_modules/bin could not run, same bug as in this issue. Cygwin also displays the same error. Here is the error:

$ npm test

> mitm@1.4.0 test C:\projects\node-mitm
> make test

C:\projects\node-mitm\node_modules\.bin\_mocha:2
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
          ^^^^^^^

SyntaxError: missing ) after argument list
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:607:28)
    at Object.Module._extensions..js (module.js:654:10)
    at Module.load (module.js:556:32)
    at tryModuleLoad (module.js:499:12)
    at Function.Module._load (module.js:491:3)
    at Function.Module.runMain (module.js:684:10)
    at startup (bootstrap_node.js:187:16)
    at bootstrap_node.js:608:3
make: *** [Makefile:9: test] Error 1
npm ERR! Test failed.  See above for more details.
moll commented 5 years ago

I think that's because node_modules/.bin/_mocha on Windows seems to a shell, not a JavaScript file, and my Makefile is invoking it with Node. I don't have Windows around to test, so do you mind pasting its contents somewhere (like http://gist.github.com)? I'm curious to see what it does. Thx.

moll commented 5 years ago

Found an example of it in the issue you linked to, too. Yeah, I don't think I can fix that in any convenient way. I find it's useful to be able to pass a path to Node.js via the Makefile, but given that those bin files on Windows aren't JavaScript files and hard-code Node's executable, that'll never work.

For now, if you want to run those tests through Make on Windows, you'll have to unset the default NODE variable like such make spec NODE=. That'll invoke _mocha without passing it to Node.js. Sorry about that.

We can continue chatting, but I'll close the issue as we've covered the actionable parts already. :)