betamaxteam / betamax

Betamax is a tool for mocking external HTTP resources such as web services and REST APIs in your tests. The project was inspired by the VCR library for Ruby.
http://betamax.software
Apache License 2.0
470 stars 131 forks source link

does betamax work across machines? #220

Closed babarismail closed 7 years ago

babarismail commented 7 years ago

I am trying to setup betamax for our tests that run on a different machine than the service under test. I tried setting up a mock server that starts the betamax recorder on startup. Now when i redirect requests through this server, i dont see betamax playing back from the tapes nor it acknowledges that any requests are coming through.

I thought starting betamax recorder on some port (unblocked of course!) and routing my requests through that port would work. It works fine on the same box but I can't seem to get it working when the mock server is deployed on another box.

Any ideas?

cowboygneox commented 7 years ago

Betamax is not designed to work in this way, though I suppose it could be adjusted to do so. You have to ensure that your proxy settings are correctly configured to hit Betamax, and even then, the behavior is undefined. I've thought about adding this sort of route in a future version of Betamax, but I may completely diverge from Java to do that.

What is your reason for wanting to do this?

babarismail commented 7 years ago

what would need to be configured in betamax to make it work? In the configuration, there is a property called proxyHost. What is the benefit of that if it is always going to be localhost?

I assume betamax listens on a port and matches whatever traffic responses it can. Why would there be any difference between same machine requests and cross machine requests?

I was thinking on writing a TCP port listener that forwards traffic to the port betamax is listening on. Will that work? Our test structure is complex as multiple teams' tests call into our service and we prefer that they don't mock our service. So we decided to have a mock server that our service under test proxies all 3rd party requests through. We also prefer to keep the mock code decoupled from product code so we dont want to make a code change in the product code to start the mock server.

cowboygneox commented 7 years ago

Will you be using HTTPS?

babarismail commented 7 years ago

yes we will be using https

babarismail commented 7 years ago

Our https scenario works just fine but again on the same machine

cowboygneox commented 7 years ago

So in essence you want to turn Betamax into a forward proxy? You want to use it as an actual MITM between clients and your service? Hypothetically this is possible, though I do not have a lot of advice for getting it done. I am not sure if there is any poorly implemented bindings to localhost that would prevent such a use.

Being that Betamax was not designed to function in this capacity, I can only offer some high-level guidance for you going forward. I would figure out how to get Betamax to launch as a stand-alone application, and use simple curl scripts to try and stress it's recording capabilities. Start first without HTTPS, and then try HTTPS once HTTP is working. It may take some time to get to that point.

If you do get Betamax working this way, please report back, and we can try to incorporate it into the project.

babarismail commented 7 years ago

I was thinking about keeping the forward proxy separate from Betamax at this point but if it works then I can contribute it to betamax. The thing I don't understand is why cross machine case is different from same machine? What is betamax using that imposes this restriction?

Running betamax as a standalone project was fairly straightforward to do. We just deployed a REST service that had onStart and onShutdown hooks where we start and stop the recorder.

cowboygneox commented 7 years ago

Betamax 1.x was originally a hack similar to that of vcr. In 2.x, we started moving it to a standalone attachment. It's not that there is a restriction, it just wasn't designed for your use.

babarismail commented 7 years ago

So here is how i got it to work: I wrote a simple forwarding proxy program that forwards the traffic from one port to the one betmax is running on. The program consists of spinning up 2 threads: the first one reads data from the client and writes it to the betamax connection. the second threads does just the opposite: reads from betamax's stream and writes it back to the client. works for both http and https. I haven't looked at what betamax uses that blocks it from working across machines but i don't see a reason why it can't be adjusted. Encapsulating all this logic in betamax will make it even more useful. Regardless, it is a great tool that will make our lives easier :)

cowboygneox commented 7 years ago

@babarismail is there potential to put this on a branch somewhere I can see it?

cowboygneox commented 7 years ago

I'd like to leave this open until I create an action item from it.

babarismail commented 7 years ago

This is a good example: http://examples.oreilly.com/jenut/ProxyServer.java

I wrote something similar but with some of our infra related housekeeping. I then start betamax recorder before serverSocket.accept(). I can try to create a personal github repo for you to see if you want to see exactly what i did. Otherwise this is a very good starting point

cowboygneox commented 7 years ago

Moving this to Trello: https://trello.com/c/MEwtr6m2.