do-until with uri module

So I am running ‘canary’ tests post CI and pre deployment to test if the newest code runs without error in a real environment.

The tests are just hitting a url and checking that it returns 200. Sometimes it takes a little bit for the process I’m testing against to become available which means my tests will fail if I run them before the process is ready to serve requests. At first I was just having a pause in between starting the process and running the test to give it time to come up, but this is very brittle because that time can vary, and it is also very inefficient if I wait for longer than I need to.

I then thought I could solve these problems by using a do-until loop. The problem is, there is nothing I can check for in the registered var that exists on both failure and success.

Example:

`

This doesn’t help because when the test fails because the url isn’t ready to serve requests, the register variable only contains something like:

{ "changed": false, "failed": true, "msg": "Socket error: [Errno 104] Connection reset by peer to https://0.0.0.0:3030/api/canary" }

Therefor, the until will fail with:

{ "failed": true, "msg": "ERROR! The conditional check 'result['status'] == 200' failed. The error was: ERROR! error while evaluating conditional (result['status'] == 200): ERROR! 'dict object' has no attribute 'status'" }

I thought that maybe “failed”: false would exist in successful tests, but that is not the case.

It’s kind of a catch-22 because if the test succeeds the first time, I don’t need the do-until, but if it fails, then there is nothing for the until to check against.

Any ideas on how to handle this?

Maybe use the |default filter like:

until: result[‘status’]|default(0) == 200

that worked! You’re amazing.

One more question:

How do I use default for a variable more than one level down?

such as

result['json']['ok'] | default(0) == 1

that gives me

FAILED! => { "failed": true, "msg": "ERROR! The conditional check 'result['json']['ok']|default(0) == 1' failed. The error was: ERROR! error while evaluating conditional (result['json']['ok']|default(0) == 1): ERROR! 'dict object' has no attribute 'json'"}

That is a little more complicated:

result[‘json’]|default(dict())[‘ok’]|default(0)

There are other ways too, but effectively you have to do it at each level.