Fix index shifting when earlier stub is deleted
Expected behavior
The key to a stub stays the same after an earlier stub is deleted.
When 2 tests adds a stub to the same imposter, and then the first test deletes its stub, the second test should still be able to give a unique identifier to Mountebank to delete the stub it created.
Actual behavior
The key that the DELETE endpoint takes for deleting a stub (DELETE imposters/{port}/stubs/{key}) is an index in an array. When deleting a stub, all the keys that come after in the array are all shifted to the left by one.
If we had stubs [a, b, c, d], and then pass index 1 to delete b, the new array becomes [a, c, d]. you would now have to pass index 1 to delete c and index 2 to delete d, instead of their original keys 2 and 3.
Thus, because there is no unique identifier on a stub it's impossible to delete a stub reliably for tests running in parallel. Even if you tried to not keep all keys in memory per stub for each test, and instead get all stubs to get the index for your stub to pass to delete, a different test could have deleted an earlier stub during your read & delete and the index you have would be stale.
Steps to reproduce
Start mountebank on separate terminal. Assuming you have mb, perhaps through npm install -g mountebank
mb start --loglevel debug
On a different terminal acting as a client:
# Create HTTP Imposter
curl -i -X POST -H 'Content-Type: application/json' http://localhost:2525/imposters --data '{
"port": 4545,
"protocol": "http",
"stubs": []
}'
# Add stub 1
curl -i -X POST -H 'Content-Type: application/json' http://localhost:2525/imposters/4545/stubs --data '{
"stub": {
"predicates": [
{
"equals": {
"body": { "id": 123 }
}
}
],
"responses": [
{ "is": { "body": { "balance": 1e6 } } }
]
}
}'
# Add stub 2
curl -i -X POST -H 'Content-Type: application/json' http://localhost:2525/imposters/4545/stubs --data '{
"stub": {
"predicates": [
{
"equals": {
"body": { "id": 234 }
}
}
],
"responses": [
{ "is": { "body": { "balance": 5e6 } } }
]
}
}'
# Delete stub 1
curl -i -X DELETE -H 'Content-Type: application/json' http://localhost:2525/imposters/4545/stubs/1
# Delete stub 2
curl -i -X DELETE -H 'Content-Type: application/json' http://localhost:2525/imposters/4545/stubs/2
The last curl gives an error that the index is not valid. This is because the 2nd stub was moved from index 2 to index 1. index 2 no longer exists.
HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
Content-Length: 176
Date: Tue, 27 Apr 2021 16:27:49 GMT
Connection: keep-alive
{
"errors": [
{
"code": "bad data",
"message": "'stubIndex' must be a valid integer, representing the array index position of the stub to replace"
}
]
}
You would actually have to pass index 1 to delete the 2nd stub.
Software versions used
OS : N/A
mountebank : 2.4.0
node.js : v12.18.2
Installation method : npm
Log contents in mb.log when running mb --loglevel debug
{"message":"[mb:2525] mountebank v2.4.0 now taking orders - point your browser to http://localhost:2525/ for help","level":"info","timestamp":"2021-04-27T16:36:11.587Z"}
{"message":"[mb:2525] config: {\"options\":{\"port\":2525,\"noParse\":false,\"no-parse\":false,\"formatter\":\"mountebank-formatters\",\"pidfile\":\"mb.pid\",\"allowInjection\":false,\"allow-injection\":false,\"localOnly\":false,\"local-only\":false,\"ipWhitelist\":[\"*\"],\"ip-whitelist\":\"*\",\"mock\":false,\"debug\":false,\"heroku\":false,\"protofile\":\"protocols.json\",\"origin\":false,\"log\":{\"level\":\"debug\",\"transports\":{\"console\":{\"colorize\":true,\"format\":\"%level: %message\"},\"file\":{\"path\":\"mb.log\",\"format\":\"json\"}}}},\"process\":{\"nodeVersion\":\"v12.18.2\",\"architecture\":\"x64\",\"platform\":\"darwin\"}}","level":"debug","timestamp":"2021-04-27T16:36:11.588Z"}
{"message":"[mb:2525] POST /imposters","level":"info","timestamp":"2021-04-27T16:37:05.251Z"}
{"message":"[mb:2525] ::1:51809 => {\"port\":4545,\"protocol\":\"http\",\"stubs\":[]}","level":"debug","timestamp":"2021-04-27T16:37:05.253Z"}
{"message":"[http:4545] Open for business...","level":"info","timestamp":"2021-04-27T16:37:05.260Z"}
{"message":"[mb:2525] POST /imposters/4545/stubs","level":"info","timestamp":"2021-04-27T16:37:08.954Z"}
{"message":"[mb:2525] {\"isValid\":true,\"errors\":[]}","level":"error","timestamp":"2021-04-27T16:37:08.955Z"}
{"message":"[mb:2525] POST /imposters/4545/stubs","level":"info","timestamp":"2021-04-27T16:37:12.084Z"}
{"message":"[mb:2525] {\"isValid\":true,\"errors\":[]}","level":"error","timestamp":"2021-04-27T16:37:12.085Z"}
{"message":"[mb:2525] DELETE /imposters/4545/stubs/1","level":"info","timestamp":"2021-04-27T16:37:16.808Z"}
{"message":"[mb:2525] DELETE /imposters/4545/stubs/2","level":"info","timestamp":"2021-04-27T16:37:18.292Z"}
{"message":"[mb:2525] error changing stubs: [{\"code\":\"bad data\",\"message\":\"'stubIndex' must be a valid integer, representing the array index position of the stub to replace\"}]","level":"error","timestamp":"2021-04-27T16:37:18.293Z"}
{"message":"[mb:2525] Adios - see you soon?","level":"info","timestamp":"2021-04-27T16:37:33.695Z"}
Hello @bbyars
We also faced the same issue in our codebase. Do you mind if I work on this and contribute a PR?
Thanks in advance :)
Not at all!
On Sun, Mar 19, 2023 at 11:10 PM Alex Xandra Albert Sim < @.***> wrote:
Hello @bbyars https://github.com/bbyars
We also faced the same issue in our codebase. Do you mind if I work on this and contribute a PR?
Thanks in advance :)
— Reply to this email directly, view it on GitHub https://github.com/bbyars/mountebank/issues/612#issuecomment-1475597230, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAARFP5UCYTBUFUTEBAUUTLW47KEVANCNFSM43VLEYAQ . You are receiving this because you were mentioned.Message ID: @.***>