Mock/fake a Geo primary or secondary endpoint to allow for writting integration tests in RSpec
Context
We currently lack a way to simulate a second endpoint when testing Geo.
The alternative we have been using today doesn't scale well: the QA
folder, which requires a full cluster installation to run end-to-end tests. They are hard to code, slow to run, and is not a fit for the more granular requirement of "unit/integration tests" we need today.
Some examples of what can be done with a "sandboxed/mocked endpoint": validate blob transfer logic, validate git repository transfer logic, validate OAuth flow, etc.
How
I've read a few articles that gave me some ideas. What I believe is that we would need a "simple sinatra/rack level application" that would run only during a specific RSpec context. That second process could be set up so that it simulates a specific endpoint responses.
Here are some links with pieces of what we need to build in order to have that new capability:
- https://thoughtbot.com/blog/faking-remote-services-with-rack-test
- https://nextlinklabs.com/insights/using-sinatra-to-mock-3rd-party-apis-inside-a-rails-test-suite
- http://roda.jeremyevans.net/ (use roda instead of sinatra, as its cleaner)
- https://www.johnnunemaker.com/ruby-rack-background-thread/
Some related solutions:
- https://github.com/jnunemaker/brow/blob/b9ff7652b1872879f68665c9f325c0691a8d4bc8/test/support/fake_server.rb
- https://github.com/thoughtbot/capybara_discoball
This is specially important for when the code that makes the request is not in the same "process" where the test runs. For example, a registry notification would not be part of the rspec context, so you need a separate endpoint.
Another example is a request that is triggered by gitaly. That is not part of existing rspec context, and therefore we cannot "mock" anything from the code, but we could direct it to a separate "process/address/port" that runs a specifically crafted code to test a specific behavior.
Another example is when we want to validate blob's HTTP transfer logic, we need to "mock" an endpoint with a variety of behavior, from giving a corrupt file, to authentication logic etc.