do-until with uri module

2,800 views
Skip to first unread message

Marcus Morris

unread,
May 20, 2016, 3:57:16 PM5/20/16
to Ansible Project
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:

- name: run test
  uri
:
    url
: "https://0.0.0.0:3030/api/canary"
    validate_certs
: no
 
register: result
 
until: result['status'] == 200

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?


Matt Martz

unread,
May 20, 2016, 3:59:13 PM5/20/16
to ansible...@googlegroups.com
Maybe use the |default filter like:

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

--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/f41735fb-ff5b-44a5-b898-ae645ff07e23%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Matt Martz
@sivel
sivel.net

Marcus Morris

unread,
May 20, 2016, 4:00:47 PM5/20/16
to Ansible Project
that worked! You're amazing.

Marcus Morris

unread,
May 20, 2016, 6:56:55 PM5/20/16
to Ansible Project
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'"}




Matt Martz

unread,
May 20, 2016, 7:43:42 PM5/20/16
to ansible...@googlegroups.com
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.

--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
Message has been deleted
0 new messages