From 18ec800264d9fcaefced41329c5be973f36cca1e Mon Sep 17 00:00:00 2001 From: Greg Schueler Date: Fri, 7 Nov 2014 11:12:02 -0800 Subject: [PATCH 1/7] Test expected API v11 response --- .../rundeck/api/parser/PagedResultParser.java | 11 +- .../org/rundeck/api/RundeckClientTest.java | 126 ++++++ .../betamax/tapes/get_executions_v11.yaml | 419 ++++++++++++++++++ 3 files changed, 554 insertions(+), 2 deletions(-) create mode 100644 src/test/resources/betamax/tapes/get_executions_v11.yaml diff --git a/src/main/java/org/rundeck/api/parser/PagedResultParser.java b/src/main/java/org/rundeck/api/parser/PagedResultParser.java index 3eed01c..3389a87 100644 --- a/src/main/java/org/rundeck/api/parser/PagedResultParser.java +++ b/src/main/java/org/rundeck/api/parser/PagedResultParser.java @@ -26,6 +26,7 @@ package org.rundeck.api.parser; import org.dom4j.Element; import org.dom4j.Node; +import org.rundeck.api.RundeckApiException; import org.rundeck.api.util.PagedResults; import java.util.*; @@ -38,7 +39,7 @@ import java.util.*; */ public class PagedResultParser implements XmlNodeParser> { ListParser itemParser; - String xpath; + private String xpath; /** * Create a PagedResultParser @@ -54,7 +55,9 @@ public class PagedResultParser implements XmlNodeParser> { @Override public PagedResults parseXmlNode(Node node) { Node pagedNodeContainer = node.selectSingleNode(xpath); - + if(null==pagedNodeContainer) { + throw new RundeckApiException("XML content did not match XPATH expression: " + xpath); + } Element el = (Element) pagedNodeContainer; final int max = integerAttribute(el, "max", -1); final int offset = integerAttribute(el, "offset", -1); @@ -113,4 +116,8 @@ public class PagedResultParser implements XmlNodeParser> { } return parseMax; } + + public String getXpath() { + return xpath; + } } diff --git a/src/test/java/org/rundeck/api/RundeckClientTest.java b/src/test/java/org/rundeck/api/RundeckClientTest.java index 21f306f..d4d844e 100644 --- a/src/test/java/org/rundeck/api/RundeckClientTest.java +++ b/src/test/java/org/rundeck/api/RundeckClientTest.java @@ -402,6 +402,132 @@ public class RundeckClientTest { .build(), 2L, 0L); assertPageResults(adhocTest, 2, 2, 2, 0, 2); } + @Test + @Betamax(tape = "get_executions_v11", + mode = TapeMode.READ_ONLY, + match = {MatchRule.uri, MatchRule.headers, MatchRule.method, MatchRule.path, MatchRule.query}) + public void getExecutionsV11() throws Exception { + + RundeckClient client = createClient(TEST_TOKEN_7, 11); + + + final String projectName = "blah"; + final PagedResults jobTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .job("test job") + .build(), + 2L, + 0L); + assertPageResults(jobTest, 2, 2, 2, 0, 2); + final PagedResults jobExactTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .jobExact("test job") + .build(), + 2L, + 0L); + assertPageResults(jobExactTest, 2, 2, 2, 0, 2); + final PagedResults excludeJobTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .excludeJob("test job") + .build(), + 2L, + 0L); + assertPageResults(excludeJobTest, 2, 2, 2, 0, 2); + final PagedResults excludeJobExactTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .excludeJobExact("test job") + .build(), + 2L, + 0L); + assertPageResults(excludeJobExactTest, 2, 2, 2, 0, 2); + final PagedResults descriptionTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .description("a description") + .build(), 2L, 0L); + assertPageResults(descriptionTest, 2, 2, 2, 0, 2); + final PagedResults abortedbyTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .abortedby("admin") + .build(), + 2L, + 0L); + assertPageResults(abortedbyTest, 1, 1, 2, 0, 1); + final PagedResults beginTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .begin(new Date(1347581178168L)) + .build(), 2L, 0L); + assertPageResults(beginTest, 2, 2, 2, 0, 6); + final PagedResults endTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .end(new Date(1415388156385L)) + .build(), 2L, 0L); + assertPageResults(endTest, 2, 2, 2, 0, 4); + final List excludeJobIdList = Arrays.asList("123", "456"); + final PagedResults excludeJobIdListTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .excludeJobIdList(excludeJobIdList) + .build(), 2L, 0L); + assertPageResults(excludeJobIdListTest, 2, 2, 2, 0, 4); + final List jobList = Arrays.asList("fruit/mango", "fruit/lemon"); + final PagedResults jobListTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .jobList(jobList) + .build(), 2L, 0L); + assertPageResults(jobListTest, 2, 2, 2, 0, 2); + final List excludeJobList = Arrays.asList("a/path/job1", "path/to/job2"); + final PagedResults excludeJobListTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .excludeJobList(excludeJobList) + .build(), 2L, 0L); + assertPageResults(excludeJobListTest, 2, 2, 2, 0, 4); + final List list = Arrays.asList("9aa33253-17a3-4dce-890c-e5f10f9f00d6", + "2dd94199-00c4-4690-9b4d-beda4812bed0"); + final PagedResults jobIdListTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .jobIdList(list) + .build(), 2L, 0L); + assertPageResults(jobIdListTest, 2, 2, 2, 0, 2); + final PagedResults groupPathTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .groupPath("fruit") + .build(), + 2L, + 0L); + assertPageResults(groupPathTest, 2, 2, 2, 0, 2); + final PagedResults groupPathExactTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .groupPathExact("fruit") + .build(), 2L, 0L); + assertPageResults(groupPathExactTest, 2, 2, 2, 0, 2); + + final PagedResults excludeGroupPathTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .excludeGroupPath("fruit") + .build(), + 2L, + 0L); + assertPageResults(excludeGroupPathTest, 2, 2, 2, 0, 2); + final PagedResults excliudeGroupPathExactTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .excludeGroupPathExact("fruit") + .build(), 2L, 0L); + assertPageResults(excliudeGroupPathExactTest, 2, 2, 2, 0, 2); + + final PagedResults recentTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .recent("1h").build(), 2L, 0L); + assertPageResults(recentTest, 2, 2, 2, 0, 2); + final PagedResults statusTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .status(RundeckExecution.ExecutionStatus.SUCCEEDED) + .build(), 2L, 0L); + assertPageResults(statusTest, 2, 2, 2, 0, 3); + final PagedResults adhocTest = client.getExecutions(ExecutionQuery.builder() + .project(projectName) + .adhoc(true) + .build(), 2L, 0L); + assertPageResults(adhocTest, 2, 2, 2, 0, 2); + } /** * Test paging values from results diff --git a/src/test/resources/betamax/tapes/get_executions_v11.yaml b/src/test/resources/betamax/tapes/get_executions_v11.yaml new file mode 100644 index 0000000..ae592b0 --- /dev/null +++ b/src/test/resources/betamax/tapes/get_executions_v11.yaml @@ -0,0 +1,419 @@ +!tape +name: get_executions_v11 +interactions: +- recorded: 2014-11-07T23:18:13.076Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?jobFilter=test+job&project=blah&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Expires: Thu, 01 Jan 1970 00:00:00 GMT + Server: Jetty(7.6.0.v20120127) + Set-Cookie: JSESSIONID=1jt4f1ctz8i6rfsou34u5suz2;Path=/ + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T18:51:44Z\n 2014-11-07T18:51:49Z\n \n test job\n\ + \ \n blah\n a description\n \n sleep 5\n \n \n \n \n\ + \ \n \n admin\n 2014-11-07T18:51:32Z\n 2014-11-07T18:51:39Z\n\ + \ admin\n \n test job\n \n blah\n a description\n\ + \ \n sleep 5\n \n \n \n \n \n \n" +- recorded: 2014-11-07T23:18:13.426Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?jobExactFilter=test+job&project=blah&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T18:51:44Z\n 2014-11-07T18:51:49Z\n \n test job\n\ + \ \n blah\n a description\n \n sleep 5\n \n \n \n \n\ + \ \n \n admin\n 2014-11-07T18:51:32Z\n 2014-11-07T18:51:39Z\n\ + \ admin\n \n test job\n \n blah\n a description\n\ + \ \n sleep 5\n \n \n \n \n \n \n" +- recorded: 2014-11-07T23:18:13.591Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?excludeJobFilter=test+job&project=blah&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T18:54:10Z\n 2014-11-07T18:54:16Z\n \n mango\n \ + \ fruit\n blah\n \n \n sleep 5\n \n \n \n \n\ + \ \n \n admin\n 2014-11-07T18:54:08Z\n 2014-11-07T18:54:14Z\n \n lemon\n fruit\n blah\n \n\ + \ \n sleep 5\n \n \n \n \n \n \n" +- recorded: 2014-11-07T23:18:13.748Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?excludeJobExactFilter=test+job&project=blah&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T18:54:10Z\n 2014-11-07T18:54:16Z\n \n mango\n \ + \ fruit\n blah\n \n \n sleep 5\n \n \n \n \n\ + \ \n \n admin\n 2014-11-07T18:54:08Z\n 2014-11-07T18:54:14Z\n \n lemon\n fruit\n blah\n \n\ + \ \n sleep 5\n \n \n \n \n \n \n" +- recorded: 2014-11-07T23:18:13.897Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?project=blah&descFilter=a+description&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T18:51:44Z\n 2014-11-07T18:51:49Z\n \n test job\n\ + \ \n blah\n a description\n \n sleep 5\n \n \n \n \n\ + \ \n \n admin\n 2014-11-07T18:51:32Z\n 2014-11-07T18:51:39Z\n\ + \ admin\n \n test job\n \n blah\n a description\n\ + \ \n sleep 5\n \n \n \n \n \n \n" +- recorded: 2014-11-07T23:18:14.025Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?project=blah&abortedbyFilter=admin&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T18:51:32Z\n 2014-11-07T18:51:39Z\n admin\n \n\ + \ test job\n \n blah\n a description\n \n sleep 5\n \n \n \n \n \n \n" +- recorded: 2014-11-07T23:18:14.155Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?project=blah&begin=2012-09-14T00%3A06%3A18Z&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T23:17:55Z\n\ + \ 2014-11-07T23:17:56Z\n echo bye ; false\n \n \n \n \n \n \n admin\n 2014-11-07T23:17:47Z\n 2014-11-07T23:17:50Z\n\ + \ echo hi ; false\n \n \n \n \n \n \n" +- recorded: 2014-11-07T23:19:50.560Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?project=blah&end=2014-11-07T19%3A22%3A36Z&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Expires: Thu, 01 Jan 1970 00:00:00 GMT + Server: Jetty(7.6.0.v20120127) + Set-Cookie: JSESSIONID=1olgmevldd8n2d4lib3pzifep;Path=/ + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T18:54:10Z\n 2014-11-07T18:54:16Z\n \n mango\n \ + \ fruit\n blah\n \n \n sleep 5\n \n \n \n \n\ + \ \n \n admin\n 2014-11-07T18:54:08Z\n 2014-11-07T18:54:14Z\n \n lemon\n fruit\n blah\n \n\ + \ \n sleep 5\n \n \n \n \n \n \n" +- recorded: 2014-11-07T23:19:50.701Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?project=blah&excludeJobIdListFilter=123&excludeJobIdListFilter=456&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T18:54:10Z\n 2014-11-07T18:54:16Z\n \n mango\n \ + \ fruit\n blah\n \n \n sleep 5\n \n \n \n \n\ + \ \n \n admin\n 2014-11-07T18:54:08Z\n 2014-11-07T18:54:14Z\n \n lemon\n fruit\n blah\n \n\ + \ \n sleep 5\n \n \n \n \n \n \n" +- recorded: 2014-11-07T23:19:50.837Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?project=blah&jobListFilter=fruit%2Fmango&jobListFilter=fruit%2Flemon&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T18:54:10Z\n 2014-11-07T18:54:16Z\n \n mango\n \ + \ fruit\n blah\n \n \n sleep 5\n \n \n \n \n\ + \ \n \n admin\n 2014-11-07T18:54:08Z\n 2014-11-07T18:54:14Z\n \n lemon\n fruit\n blah\n \n\ + \ \n sleep 5\n \n \n \n \n \n \n" +- recorded: 2014-11-07T23:19:50.966Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?project=blah&excludeJobListFilter=a%2Fpath%2Fjob1&excludeJobListFilter=path%2Fto%2Fjob2&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T18:54:10Z\n 2014-11-07T18:54:16Z\n \n mango\n \ + \ fruit\n blah\n \n \n sleep 5\n \n \n \n \n\ + \ \n \n admin\n 2014-11-07T18:54:08Z\n 2014-11-07T18:54:14Z\n \n lemon\n fruit\n blah\n \n\ + \ \n sleep 5\n \n \n \n \n \n \n" +- recorded: 2014-11-07T23:19:51.097Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?project=blah&jobIdListFilter=9aa33253-17a3-4dce-890c-e5f10f9f00d6&jobIdListFilter=2dd94199-00c4-4690-9b4d-beda4812bed0&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T18:54:10Z\n 2014-11-07T18:54:16Z\n \n mango\n \ + \ fruit\n blah\n \n \n sleep 5\n \n \n \n \n\ + \ \n \n admin\n 2014-11-07T18:54:08Z\n 2014-11-07T18:54:14Z\n \n lemon\n fruit\n blah\n \n\ + \ \n sleep 5\n \n \n \n \n \n \n" +- recorded: 2014-11-07T23:19:51.229Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?project=blah&groupPath=fruit&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T18:54:10Z\n 2014-11-07T18:54:16Z\n \n mango\n \ + \ fruit\n blah\n \n \n sleep 5\n \n \n \n \n\ + \ \n \n admin\n 2014-11-07T18:54:08Z\n 2014-11-07T18:54:14Z\n \n lemon\n fruit\n blah\n \n\ + \ \n sleep 5\n \n \n \n \n \n \n" +- recorded: 2014-11-07T23:19:51.358Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?project=blah&groupPathExact=fruit&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T18:54:10Z\n 2014-11-07T18:54:16Z\n \n mango\n \ + \ fruit\n blah\n \n \n sleep 5\n \n \n \n \n\ + \ \n \n admin\n 2014-11-07T18:54:08Z\n 2014-11-07T18:54:14Z\n \n lemon\n fruit\n blah\n \n\ + \ \n sleep 5\n \n \n \n \n \n \n" +- recorded: 2014-11-07T23:19:51.483Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?project=blah&excludeGroupPath=fruit&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T18:51:44Z\n 2014-11-07T18:51:49Z\n \n test job\n\ + \ \n blah\n a description\n \n sleep 5\n \n \n \n \n\ + \ \n \n admin\n 2014-11-07T18:51:32Z\n 2014-11-07T18:51:39Z\n\ + \ admin\n \n test job\n \n blah\n a description\n\ + \ \n sleep 5\n \n \n \n \n \n \n" +- recorded: 2014-11-07T23:19:51.607Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?project=blah&excludeGroupPathExact=fruit&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T18:51:44Z\n 2014-11-07T18:51:49Z\n \n test job\n\ + \ \n blah\n a description\n \n sleep 5\n \n \n \n \n\ + \ \n \n admin\n 2014-11-07T18:51:32Z\n 2014-11-07T18:51:39Z\n\ + \ admin\n \n test job\n \n blah\n a description\n\ + \ \n sleep 5\n \n \n \n \n \n \n" +- recorded: 2014-11-07T23:19:51.724Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?project=blah&recentFilter=1h&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T23:17:55Z\n\ + \ 2014-11-07T23:17:56Z\n echo bye ; false\n \n \n \n \n \n \n admin\n 2014-11-07T23:17:47Z\n 2014-11-07T23:17:50Z\n\ + \ echo hi ; false\n \n \n \n \n \n \n" +- recorded: 2014-11-07T23:19:51.845Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?project=blah&statusFilter=succeeded&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T18:54:10Z\n 2014-11-07T18:54:16Z\n \n mango\n \ + \ fruit\n blah\n \n \n sleep 5\n \n \n \n \n\ + \ \n \n admin\n 2014-11-07T18:54:08Z\n 2014-11-07T18:54:14Z\n \n lemon\n fruit\n blah\n \n\ + \ \n sleep 5\n \n \n \n \n \n \n" +- recorded: 2014-11-07T23:20:12.975Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/executions?project=blah&adhoc=true&max=2&offset=0 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Expires: Thu, 01 Jan 1970 00:00:00 GMT + Server: Jetty(7.6.0.v20120127) + Set-Cookie: JSESSIONID=11ubcx5ejb1sr6nycorkmdrg3;Path=/ + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-07T23:17:55Z\n\ + \ 2014-11-07T23:17:56Z\n echo bye ; false\n \n \n \n \n \n \n admin\n 2014-11-07T23:17:47Z\n 2014-11-07T23:17:50Z\n\ + \ echo hi ; false\n \n \n \n \n \n \n" From c8e1315612ab873f075a6b63ec46838636b08bb5 Mon Sep 17 00:00:00 2001 From: Greg Schueler Date: Fri, 7 Nov 2014 15:23:12 -0800 Subject: [PATCH 2/7] Patch rundeck API v11 bug for execution query results --- .../java/org/rundeck/api/RundeckClient.java | 19 ++++++++-- .../parser/PagedResultParser_BugPatchV11.java | 35 +++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/rundeck/api/parser/PagedResultParser_BugPatchV11.java diff --git a/src/main/java/org/rundeck/api/RundeckClient.java b/src/main/java/org/rundeck/api/RundeckClient.java index 8ada6d9..101bf6d 100644 --- a/src/main/java/org/rundeck/api/RundeckClient.java +++ b/src/main/java/org/rundeck/api/RundeckClient.java @@ -1587,13 +1587,26 @@ public class RundeckClient implements Serializable { .param(new ExecutionQueryParameters(query)) .param("max", max) .param("offset", offset), - new PagedResultParser( - new ListParser(new ExecutionParser(), "execution"), - rootXpath()+"/executions" + patchApiV11Response( + new PagedResultParser( + new ListParser(new ExecutionParser(), "execution"), + rootXpath() + "/executions" + ) ) ); } + /** + * Fix potential buggy response from Rundeck, where <result> wrapper exists + * even if it should not. + * @param parser + * @return + */ + private XmlNodeParser> patchApiV11Response + (final PagedResultParser parser) { + return new PagedResultParser_BugPatchV11(parser); + } + /** * Get a single execution, identified by the given ID * diff --git a/src/main/java/org/rundeck/api/parser/PagedResultParser_BugPatchV11.java b/src/main/java/org/rundeck/api/parser/PagedResultParser_BugPatchV11.java new file mode 100644 index 0000000..083b3d1 --- /dev/null +++ b/src/main/java/org/rundeck/api/parser/PagedResultParser_BugPatchV11.java @@ -0,0 +1,35 @@ +package org.rundeck.api.parser; + +import org.dom4j.DocumentHelper; +import org.dom4j.Element; +import org.dom4j.Node; +import org.rundeck.api.util.PagedResults; + +/** + * WRaps a {@link PagedResultParser} to detect whether the result XML incorrectly is wrapped with a + * <result> element. + * + * @author Greg Schueler + * @since 2014-11-07 + */ +public class PagedResultParser_BugPatchV11 implements XmlNodeParser> { + PagedResultParser parser; + + public PagedResultParser_BugPatchV11(final PagedResultParser parser) { + this.parser = parser; + } + + @Override public PagedResults parseXmlNode(final Node node) { + Node sourceNode = node; + final Node tested = sourceNode.selectSingleNode(parser.getXpath()); + if (null == tested && !parser.getXpath().startsWith("result")) { + //prepend /result + if (null != sourceNode.selectSingleNode("result" + parser.getXpath())) { + sourceNode = sourceNode.selectSingleNode("result" + parser.getXpath()); + sourceNode.getParent().remove(sourceNode); + DocumentHelper.createDocument((Element) sourceNode); + } + } + return parser.parseXmlNode(sourceNode); + } +} From 8cc48ecd89952080fba13be6020f65f662c69898 Mon Sep 17 00:00:00 2001 From: Greg Schueler Date: Mon, 10 Nov 2014 11:14:27 -0800 Subject: [PATCH 3/7] Test api v11 response for trigger job --- .../org/rundeck/api/RundeckClientTest.java | 37 +++++++++++++++++++ .../betamax/tapes/trigger_job_basic_v11.yaml | 24 ++++++++++++ .../tapes/trigger_job_basic_v11_patch.yaml | 24 ++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 src/test/resources/betamax/tapes/trigger_job_basic_v11.yaml create mode 100644 src/test/resources/betamax/tapes/trigger_job_basic_v11_patch.yaml diff --git a/src/test/java/org/rundeck/api/RundeckClientTest.java b/src/test/java/org/rundeck/api/RundeckClientTest.java index d4d844e..97b743d 100644 --- a/src/test/java/org/rundeck/api/RundeckClientTest.java +++ b/src/test/java/org/rundeck/api/RundeckClientTest.java @@ -634,6 +634,43 @@ public class RundeckClientTest { Assert.assertEquals(RundeckExecution.ExecutionStatus.RUNNING, test.getStatus()); } + @Test + @Betamax(tape = "trigger_job_basic_v11") + public void triggerJobBasic_v11() throws Exception { + RundeckClient client = createClient(TEST_TOKEN_7, 11); + + final RundeckExecution test + = client.triggerJob(RunJobBuilder.builder().setJobId("bda8b956-43a5-4eef-9c67" + + "-3f27cc0ee1a5").build()); + + Assert.assertEquals((Long) 943L, test.getId()); + Assert.assertEquals(null, test.getArgstring()); + Assert.assertEquals(null, test.getAbortedBy()); + Assert.assertEquals("echo hi there ${job.username} ; sleep 90", test.getDescription()); + Assert.assertEquals("admin", test.getStartedBy()); + Assert.assertEquals(RundeckExecution.ExecutionStatus.RUNNING, test.getStatus()); + } + + /** + * Response for API v11 incorrectly includes <result>, but we should handle this case + * @throws Exception + */ + @Test + @Betamax(tape = "trigger_job_basic_v11_patch") + public void triggerJobBasic_v11_patch() throws Exception { + RundeckClient client = createClient(TEST_TOKEN_7, 11); + + final RundeckExecution test + = client.triggerJob(RunJobBuilder.builder().setJobId("bda8b956-43a5-4eef-9c67" + + "-3f27cc0ee1a5").build()); + + Assert.assertEquals((Long) 944L, test.getId()); + Assert.assertEquals(null, test.getArgstring()); + Assert.assertEquals(null, test.getAbortedBy()); + Assert.assertEquals("echo hi there ${job.username} ; sleep 90", test.getDescription()); + Assert.assertEquals("admin", test.getStartedBy()); + Assert.assertEquals(RundeckExecution.ExecutionStatus.RUNNING, test.getStatus()); + } @Test @Betamax(tape = "trigger_job_as_user") diff --git a/src/test/resources/betamax/tapes/trigger_job_basic_v11.yaml b/src/test/resources/betamax/tapes/trigger_job_basic_v11.yaml new file mode 100644 index 0000000..d6539c5 --- /dev/null +++ b/src/test/resources/betamax/tapes/trigger_job_basic_v11.yaml @@ -0,0 +1,24 @@ +!tape +name: trigger_job_basic_v11 +interactions: +- recorded: 2014-11-08T00:00:58.749Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/job/bda8b956-43a5-4eef-9c67-3f27cc0ee1a5/run + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: application/xml;charset=UTF-8 + Expires: Thu, 01 Jan 1970 00:00:00 GMT + Server: Jetty(7.6.0.v20120127) + Set-Cookie: JSESSIONID=19ui1v6otua3h1714jv2zbkbid;Path=/ + X-Rundeck-API-Version: '12' + X-Rundeck-API-XML-Response-Wrapper: 'false' + body: !!binary |- + PGV4ZWN1dGlvbnMgY291bnQ9JzEnPgogIDxleGVjdXRpb24gaWQ9Jzk0MycgaHJlZj0naHR0cDovL2RpZ25hbjo0NDQwL2V4ZWN1dGlvbi9mb2xsb3cvOTQzJyBzdGF0dXM9J3J1bm5pbmcnIHByb2plY3Q9J2RlbW8nPgogICAgPHVzZXI+YWRtaW48L3VzZXI+CiAgICA8ZGF0ZS1zdGFydGVkIHVuaXh0aW1lPScxNDE1NDA0ODU4NTE4Jz4yMDE0LTExLTA4VDAwOjAwOjU4WjwvZGF0ZS1zdGFydGVkPgogICAgPGpvYiBpZD0nYmRhOGI5NTYtNDNhNS00ZWVmLTljNjctM2YyN2NjMGVlMWE1Jz4KICAgICAgPG5hbWU+YSBqb2I8L25hbWU+CiAgICAgIDxncm91cD48L2dyb3VwPgogICAgICA8cHJvamVjdD5kZW1vPC9wcm9qZWN0PgogICAgICA8ZGVzY3JpcHRpb24+PC9kZXNjcmlwdGlvbj4KICAgIDwvam9iPgogICAgPGRlc2NyaXB0aW9uPmVjaG8gaGkgdGhlcmUgJHtqb2IudXNlcm5hbWV9IDsgc2xlZXAgOTA8L2Rlc2NyaXB0aW9uPgogICAgPGFyZ3N0cmluZyAvPgogIDwvZXhlY3V0aW9uPgo8L2V4ZWN1dGlvbnM+ diff --git a/src/test/resources/betamax/tapes/trigger_job_basic_v11_patch.yaml b/src/test/resources/betamax/tapes/trigger_job_basic_v11_patch.yaml new file mode 100644 index 0000000..7731908 --- /dev/null +++ b/src/test/resources/betamax/tapes/trigger_job_basic_v11_patch.yaml @@ -0,0 +1,24 @@ +!tape +name: trigger_job_basic_v11_patch +interactions: +- recorded: 2014-11-08T00:05:15.235Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/job/bda8b956-43a5-4eef-9c67-3f27cc0ee1a5/run + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Expires: Thu, 01 Jan 1970 00:00:00 GMT + Server: Jetty(7.6.0.v20120127) + Set-Cookie: JSESSIONID=1dfooymrwshimhr8fe4ncoc93;Path=/ + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-08T00:05:14Z\n\ + \ \n a job\n \n demo\n \n \n echo hi there ${job.username}\ + \ ; sleep 90\n \n \n \n" From bceb1ec4c6c862d3e08ecb0f6c99b380af2923f0 Mon Sep 17 00:00:00 2001 From: Greg Schueler Date: Mon, 10 Nov 2014 11:15:23 -0800 Subject: [PATCH 4/7] Refactor apiv11 result unwrap to utility class --- .../java/org/rundeck/api/RundeckClient.java | 21 ++--- .../org/rundeck/api/parser/APIV11Helper.java | 78 +++++++++++++++++++ .../parser/PagedResultParser_BugPatchV11.java | 35 --------- 3 files changed, 85 insertions(+), 49 deletions(-) create mode 100644 src/main/java/org/rundeck/api/parser/APIV11Helper.java delete mode 100644 src/main/java/org/rundeck/api/parser/PagedResultParser_BugPatchV11.java diff --git a/src/main/java/org/rundeck/api/RundeckClient.java b/src/main/java/org/rundeck/api/RundeckClient.java index 101bf6d..a610219 100644 --- a/src/main/java/org/rundeck/api/RundeckClient.java +++ b/src/main/java/org/rundeck/api/RundeckClient.java @@ -1587,26 +1587,19 @@ public class RundeckClient implements Serializable { .param(new ExecutionQueryParameters(query)) .param("max", max) .param("offset", offset), - patchApiV11Response( + APIV11Helper.unwrapIfNeeded( new PagedResultParser( - new ListParser(new ExecutionParser(), "execution"), + new ListParser( + new ExecutionParser(), + "execution" + ), rootXpath() + "/executions" - ) + ), + rootXpath() + "/executions" ) ); } - /** - * Fix potential buggy response from Rundeck, where <result> wrapper exists - * even if it should not. - * @param parser - * @return - */ - private XmlNodeParser> patchApiV11Response - (final PagedResultParser parser) { - return new PagedResultParser_BugPatchV11(parser); - } - /** * Get a single execution, identified by the given ID * diff --git a/src/main/java/org/rundeck/api/parser/APIV11Helper.java b/src/main/java/org/rundeck/api/parser/APIV11Helper.java new file mode 100644 index 0000000..a9711b2 --- /dev/null +++ b/src/main/java/org/rundeck/api/parser/APIV11Helper.java @@ -0,0 +1,78 @@ +package org.rundeck.api.parser; + +import org.dom4j.DocumentHelper; +import org.dom4j.Element; +import org.dom4j.Node; + +/** + * Utility to handle API v11 responses with <result> wrapper element. + * + * @author Greg Schueler + * @since 2014-11-10 + */ +public class APIV11Helper { + + /** + * Detect and remove extra <result> wrapper around xml response. + * @param parser + * @param xpath + * @param + * @return + */ + public static XmlNodeParser unwrapIfNeeded( + final XmlNodeParser parser, + final String xpath + ) { + return new NodeParser_unwrap(parser, xpath); + } + + static class NodeParser_unwrap implements XmlNodeParser { + XmlNodeParser parser; + String xpath; + + public NodeParser_unwrap(final XmlNodeParser parser, final String xpath) { + this.parser = parser; + this.xpath = xpath; + } + + @Override public T parseXmlNode(final Node node) { + + Node sourceNode = unwrapResultElement(node, xpath); + return parser.parseXmlNode(sourceNode); + } + } + + /** + * Test the node for matching the xpath string, if it doesnt match, attempt to prefix it with + * "result" and match that. If that matches, return the first child of the 'result' element. + * + * @param node + * @param xpath + * + * @return + */ + public static Node unwrapResultElement(final Node node, final String xpath) { + Node sourceNode = node; + final Node tested = sourceNode.selectSingleNode(xpath); + if (null == tested && !xpath.startsWith("result")) { + //prepend /result + if (null != sourceNode.selectSingleNode("result" + xpath)) { + Node resultNode = sourceNode.selectSingleNode("result"); + if (resultNode instanceof Element) { + Element result = (Element) resultNode; + if (result.elements().size() == 1) { + + Node node1 = (Node) result.elements().get(0); + if (node1 instanceof Element) { + sourceNode = node1; + + sourceNode.getParent().remove(sourceNode); + DocumentHelper.createDocument((Element) sourceNode); + } + } + } + } + } + return sourceNode; + } +} diff --git a/src/main/java/org/rundeck/api/parser/PagedResultParser_BugPatchV11.java b/src/main/java/org/rundeck/api/parser/PagedResultParser_BugPatchV11.java deleted file mode 100644 index 083b3d1..0000000 --- a/src/main/java/org/rundeck/api/parser/PagedResultParser_BugPatchV11.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.rundeck.api.parser; - -import org.dom4j.DocumentHelper; -import org.dom4j.Element; -import org.dom4j.Node; -import org.rundeck.api.util.PagedResults; - -/** - * WRaps a {@link PagedResultParser} to detect whether the result XML incorrectly is wrapped with a - * <result> element. - * - * @author Greg Schueler - * @since 2014-11-07 - */ -public class PagedResultParser_BugPatchV11 implements XmlNodeParser> { - PagedResultParser parser; - - public PagedResultParser_BugPatchV11(final PagedResultParser parser) { - this.parser = parser; - } - - @Override public PagedResults parseXmlNode(final Node node) { - Node sourceNode = node; - final Node tested = sourceNode.selectSingleNode(parser.getXpath()); - if (null == tested && !parser.getXpath().startsWith("result")) { - //prepend /result - if (null != sourceNode.selectSingleNode("result" + parser.getXpath())) { - sourceNode = sourceNode.selectSingleNode("result" + parser.getXpath()); - sourceNode.getParent().remove(sourceNode); - DocumentHelper.createDocument((Element) sourceNode); - } - } - return parser.parseXmlNode(sourceNode); - } -} From 39fd86ae6db8c9dd8d1bd468f0c6312d9649cd52 Mon Sep 17 00:00:00 2001 From: Greg Schueler Date: Mon, 10 Nov 2014 11:16:01 -0800 Subject: [PATCH 5/7] Trigger job handles buggy api v11 response --- src/main/java/org/rundeck/api/RundeckClient.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/rundeck/api/RundeckClient.java b/src/main/java/org/rundeck/api/RundeckClient.java index a610219..7112a58 100644 --- a/src/main/java/org/rundeck/api/RundeckClient.java +++ b/src/main/java/org/rundeck/api/RundeckClient.java @@ -1085,7 +1085,16 @@ public class RundeckClient implements Serializable { if(null!=jobRun.getAsUser()) { apiPath.param("asUser", jobRun.getAsUser()); } - return new ApiCall(this).get(apiPath, new ExecutionParser(rootXpath()+"/executions/execution")); + return new ApiCall(this).get(apiPath, + APIV11Helper.unwrapIfNeeded( + new ExecutionParser( + rootXpath() + + "/executions/execution" + ), rootXpath() + + "/executions/execution" + ) + + ); } From 1f2ffeebacc0db1a2d58f3b38beea7787fb9e5f5 Mon Sep 17 00:00:00 2001 From: Greg Schueler Date: Mon, 10 Nov 2014 12:08:39 -0800 Subject: [PATCH 6/7] getExecution handles buggy xml wrapper --- src/main/java/org/rundeck/api/RundeckClient.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/rundeck/api/RundeckClient.java b/src/main/java/org/rundeck/api/RundeckClient.java index 7112a58..fb2ef09 100644 --- a/src/main/java/org/rundeck/api/RundeckClient.java +++ b/src/main/java/org/rundeck/api/RundeckClient.java @@ -1622,8 +1622,15 @@ public class RundeckClient implements Serializable { public RundeckExecution getExecution(Long executionId) throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { AssertUtil.notNull(executionId, "executionId is mandatory to get the details of an execution !"); - return new ApiCall(this).get(new ApiPathBuilder("/execution/", executionId.toString()), - new ExecutionParser(rootXpath()+"/executions/execution")); + return new ApiCall(this).get( + new ApiPathBuilder("/execution/", executionId.toString()), + APIV11Helper.unwrapIfNeeded( + new ExecutionParser( + rootXpath() + "/executions/execution" + ), + rootXpath() + "/executions/execution" + ) + ); } /** From e98a3a0ad948e3256e7898a7288a8ea68d9989c0 Mon Sep 17 00:00:00 2001 From: Greg Schueler Date: Mon, 10 Nov 2014 12:09:06 -0800 Subject: [PATCH 7/7] Add tests for api v11 responses --- .../org/rundeck/api/RundeckClientTest.java | 130 ++++++++++++++++++ .../betamax/tapes/get_execution.yaml | 25 ++++ .../betamax/tapes/get_execution_v11.yaml | 24 ++++ .../tapes/get_execution_v11_buggy.yaml | 24 ++++ .../tapes/trigger_adhoc_command_v11.yaml | 43 ++++++ .../trigger_adhoc_command_v11_buggy.yaml | 42 ++++++ .../tapes/trigger_adhoc_script_v11.yaml | 45 ++++++ .../tapes/trigger_adhoc_script_v11_buggy.yaml | 44 ++++++ 8 files changed, 377 insertions(+) create mode 100644 src/test/resources/betamax/tapes/get_execution.yaml create mode 100644 src/test/resources/betamax/tapes/get_execution_v11.yaml create mode 100644 src/test/resources/betamax/tapes/get_execution_v11_buggy.yaml create mode 100644 src/test/resources/betamax/tapes/trigger_adhoc_command_v11.yaml create mode 100644 src/test/resources/betamax/tapes/trigger_adhoc_command_v11_buggy.yaml create mode 100644 src/test/resources/betamax/tapes/trigger_adhoc_script_v11.yaml create mode 100644 src/test/resources/betamax/tapes/trigger_adhoc_script_v11_buggy.yaml diff --git a/src/test/java/org/rundeck/api/RundeckClientTest.java b/src/test/java/org/rundeck/api/RundeckClientTest.java index 97b743d..04211f6 100644 --- a/src/test/java/org/rundeck/api/RundeckClientTest.java +++ b/src/test/java/org/rundeck/api/RundeckClientTest.java @@ -275,7 +275,47 @@ public class RundeckClientTest { } Assert.assertEquals(Arrays.asList("bob"), names); } + @Test + @Betamax(tape="get_execution") + public void getExecution() throws Exception{ + RundeckClient client = createClient(TEST_TOKEN_7, 5); + RundeckExecution execution = client.getExecution(945L); + Assert.assertEquals("echo test trigger_adhoc_command", execution.getDescription()); + Assert.assertEquals("2 seconds", execution.getDuration()); + Assert.assertEquals("test", execution.getProject()); + Assert.assertEquals("admin", execution.getStartedBy()); + Assert.assertEquals(null, execution.getJob()); + Assert.assertEquals(null, execution.getAbortedBy()); + } + @Test + @Betamax(tape="get_execution_v11") + public void getExecution_v11() throws Exception{ + RundeckClient client = createClient(TEST_TOKEN_7, 11); + RundeckExecution execution = client.getExecution(945L); + Assert.assertEquals("echo test trigger_adhoc_command", execution.getDescription()); + Assert.assertEquals("2 seconds", execution.getDuration()); + Assert.assertEquals("test", execution.getProject()); + Assert.assertEquals("admin", execution.getStartedBy()); + Assert.assertEquals(null, execution.getJob()); + Assert.assertEquals(null, execution.getAbortedBy()); + } + /** + * Test incorrect <result> wrapper is handled correctly + * @throws Exception + */ + @Test + @Betamax(tape="get_execution_v11_buggy") + public void getExecution_v11_buggy() throws Exception{ + RundeckClient client = createClient(TEST_TOKEN_7, 11); + RundeckExecution execution = client.getExecution(945L); + Assert.assertEquals("echo test trigger_adhoc_command", execution.getDescription()); + Assert.assertEquals("2 seconds", execution.getDuration()); + Assert.assertEquals("test", execution.getProject()); + Assert.assertEquals("admin", execution.getStartedBy()); + Assert.assertEquals(null, execution.getJob()); + Assert.assertEquals(null, execution.getAbortedBy()); + } @Test @Betamax(tape = "get_executions", mode = TapeMode.READ_ONLY, @@ -634,6 +674,11 @@ public class RundeckClientTest { Assert.assertEquals(RundeckExecution.ExecutionStatus.RUNNING, test.getStatus()); } + + /** + * API v11 request to trigger job, with expected xml response without <result> wrapper + * @throws Exception + */ @Test @Betamax(tape = "trigger_job_basic_v11") public void triggerJobBasic_v11() throws Exception { @@ -730,6 +775,43 @@ public class RundeckClientTest { Assert.assertEquals(RundeckExecution.ExecutionStatus.SUCCEEDED, test.getStatus()); } + @Test + @Betamax(tape = "trigger_adhoc_command_v11_buggy") + public void triggerAdhocCommand_v11_buggy() throws Exception { + RundeckClient client = createClient(TEST_TOKEN_7, 11); + + final RundeckExecution test + = client.triggerAdhocCommand(RunAdhocCommandBuilder.builder() + .setProject("test") + .setCommand("echo test trigger_adhoc_command") + .build()); + + Assert.assertEquals((Long) 945L, test.getId()); + Assert.assertEquals(null, test.getArgstring()); + Assert.assertEquals(null, test.getAbortedBy()); + Assert.assertEquals("echo test trigger_adhoc_command", test.getDescription()); + Assert.assertEquals("admin", test.getStartedBy()); + Assert.assertEquals(RundeckExecution.ExecutionStatus.RUNNING, test.getStatus()); + } + @Test + @Betamax(tape = "trigger_adhoc_command_v11") + public void triggerAdhocCommand_v11() throws Exception { + RundeckClient client = createClient(TEST_TOKEN_7, 11); + + final RundeckExecution test + = client.triggerAdhocCommand(RunAdhocCommandBuilder.builder() + .setProject("test") + .setCommand("echo test trigger_adhoc_command") + .build()); + + Assert.assertEquals((Long) 946L, test.getId()); + Assert.assertEquals(null, test.getArgstring()); + Assert.assertEquals(null, test.getAbortedBy()); + Assert.assertEquals("echo test trigger_adhoc_command", test.getDescription()); + Assert.assertEquals("admin", test.getStartedBy()); + Assert.assertEquals(RundeckExecution.ExecutionStatus.RUNNING, test.getStatus()); + } + @Test @Betamax(tape = "trigger_adhoc_command_as_user") @@ -794,6 +876,54 @@ public class RundeckClientTest { Assert.assertEquals(RundeckExecution.ExecutionStatus.RUNNING, test.getStatus()); } + + /** + * Handle incorrect <result> wrapper for v11 response + * @throws Exception + */ + @Test + @Betamax(tape = "trigger_adhoc_script_v11_buggy") + public void triggerAdhocScript_v11_buggy() throws Exception { + RundeckClient client = createClient(TEST_TOKEN_7, 11); + String script = "#!/bin/bash\n" + + "echo test trigger_adhoc_script\n"; + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(script.getBytes()); + + final RundeckExecution test + = client.triggerAdhocScript(RunAdhocScriptBuilder.builder().setProject("test").setScript + (byteArrayInputStream).build()); + + Assert.assertEquals((Long) 947L, test.getId()); + Assert.assertEquals(null, test.getArgstring()); + Assert.assertEquals(null, test.getAbortedBy()); + Assert.assertEquals("#!/bin/bash\necho test trigger_adhoc_script", test.getDescription()); + Assert.assertEquals("admin", test.getStartedBy()); + Assert.assertEquals(RundeckExecution.ExecutionStatus.RUNNING, test.getStatus()); + } + /** + * Handle v11 response without <result> wrapper + * @throws Exception + */ + @Test + @Betamax(tape = "trigger_adhoc_script_v11") + public void triggerAdhocScript_v11() throws Exception { + RundeckClient client = createClient(TEST_TOKEN_7, 11); + String script = "#!/bin/bash\n" + + "echo test trigger_adhoc_script\n"; + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(script.getBytes()); + + final RundeckExecution test + = client.triggerAdhocScript(RunAdhocScriptBuilder.builder().setProject("test").setScript + (byteArrayInputStream).build()); + + Assert.assertEquals((Long) 948L, test.getId()); + Assert.assertEquals(null, test.getArgstring()); + Assert.assertEquals(null, test.getAbortedBy()); + Assert.assertEquals("#!/bin/bash\necho test trigger_adhoc_script", test.getDescription()); + Assert.assertEquals("admin", test.getStartedBy()); + Assert.assertEquals(RundeckExecution.ExecutionStatus.RUNNING, test.getStatus()); + } + @Test @Betamax(tape = "trigger_adhoc_script_as_user") public void triggerAdhocScriptAsUser() throws Exception { diff --git a/src/test/resources/betamax/tapes/get_execution.yaml b/src/test/resources/betamax/tapes/get_execution.yaml new file mode 100644 index 0000000..d460f9d --- /dev/null +++ b/src/test/resources/betamax/tapes/get_execution.yaml @@ -0,0 +1,25 @@ +!tape +name: get_execution +interactions: +- recorded: 2014-11-10T19:43:41.415Z + request: + method: GET + uri: http://rundeck.local:4440/api/5/execution/945 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 5 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Expires: Thu, 01 Jan 1970 00:00:00 GMT + Server: Jetty(7.6.0.v20120127) + Set-Cookie: JSESSIONID=1x4pkxxmmforonss2ga8ylvdc;Path=/ + X-Rundeck-API-Version: '12' + X-Rundeck-API-XML-Response-Wrapper: 'true' + body: "\n \n \n admin\n 2014-11-10T19:18:36Z\n\ + \ 2014-11-10T19:18:38Z\n echo test trigger_adhoc_command\n \n \n \n \n \ + \ \n \n" diff --git a/src/test/resources/betamax/tapes/get_execution_v11.yaml b/src/test/resources/betamax/tapes/get_execution_v11.yaml new file mode 100644 index 0000000..450b2d6 --- /dev/null +++ b/src/test/resources/betamax/tapes/get_execution_v11.yaml @@ -0,0 +1,24 @@ +!tape +name: get_execution_v11 +interactions: +- recorded: 2014-11-10T19:44:57.642Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/execution/945 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: application/xml;charset=UTF-8 + Expires: Thu, 01 Jan 1970 00:00:00 GMT + Server: Jetty(7.6.0.v20120127) + Set-Cookie: JSESSIONID=yzyycrxo7utb154qrsuggbtp6;Path=/ + X-Rundeck-API-Version: '12' + X-Rundeck-API-XML-Response-Wrapper: 'false' + body: !!binary |- + PGV4ZWN1dGlvbnMgY291bnQ9JzEnPgogIDxleGVjdXRpb24gaWQ9Jzk0NScgaHJlZj0naHR0cDovL2RpZ25hbjo0NDQwL2V4ZWN1dGlvbi9mb2xsb3cvOTQ1JyBzdGF0dXM9J3N1Y2NlZWRlZCcgcHJvamVjdD0ndGVzdCc+CiAgICA8dXNlcj5hZG1pbjwvdXNlcj4KICAgIDxkYXRlLXN0YXJ0ZWQgdW5peHRpbWU9JzE0MTU2NDcxMTY3MzknPjIwMTQtMTEtMTBUMTk6MTg6MzZaPC9kYXRlLXN0YXJ0ZWQ+CiAgICA8ZGF0ZS1lbmRlZCB1bml4dGltZT0nMTQxNTY0NzExODkzMSc+MjAxNC0xMS0xMFQxOToxODozOFo8L2RhdGUtZW5kZWQ+CiAgICA8ZGVzY3JpcHRpb24+ZWNobyB0ZXN0IHRyaWdnZXJfYWRob2NfY29tbWFuZDwvZGVzY3JpcHRpb24+CiAgICA8YXJnc3RyaW5nIC8+CiAgICA8c3VjY2Vzc2Z1bE5vZGVzPgogICAgICA8bm9kZSBuYW1lPSdkaWduYW4nIC8+CiAgICA8L3N1Y2Nlc3NmdWxOb2Rlcz4KICA8L2V4ZWN1dGlvbj4KPC9leGVjdXRpb25zPg== diff --git a/src/test/resources/betamax/tapes/get_execution_v11_buggy.yaml b/src/test/resources/betamax/tapes/get_execution_v11_buggy.yaml new file mode 100644 index 0000000..12eed0e --- /dev/null +++ b/src/test/resources/betamax/tapes/get_execution_v11_buggy.yaml @@ -0,0 +1,24 @@ +!tape +name: get_execution_v11_buggy +interactions: +- recorded: 2014-11-10T19:47:33.973Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/execution/945 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Expires: Thu, 01 Jan 1970 00:00:00 GMT + Server: Jetty(7.6.0.v20120127) + Set-Cookie: JSESSIONID=prilmlypvi8r14cvs72xu9865;Path=/ + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-10T19:18:36Z\n\ + \ 2014-11-10T19:18:38Z\n echo test trigger_adhoc_command\n \n \n \n \n \ + \ \n \n" diff --git a/src/test/resources/betamax/tapes/trigger_adhoc_command_v11.yaml b/src/test/resources/betamax/tapes/trigger_adhoc_command_v11.yaml new file mode 100644 index 0000000..c7dc62a --- /dev/null +++ b/src/test/resources/betamax/tapes/trigger_adhoc_command_v11.yaml @@ -0,0 +1,43 @@ +!tape +name: trigger_adhoc_command_v11 +interactions: +- recorded: 2014-11-10T19:37:31.471Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/run/command?project=test&exec=echo+test+trigger_adhoc_command + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: application/xml;charset=UTF-8 + Expires: Thu, 01 Jan 1970 00:00:00 GMT + Server: Jetty(7.6.0.v20120127) + Set-Cookie: JSESSIONID=1lzqzroq2oz9d1oiwcyb9qjsk8;Path=/ + X-Rundeck-API-Version: '12' + X-Rundeck-API-XML-Response-Wrapper: 'false' + body: !!binary |- + PGV4ZWN1dGlvbiBpZD0nOTQ2JyAvPg== +- recorded: 2014-11-10T19:37:31.807Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/execution/946 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: application/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + X-Rundeck-API-XML-Response-Wrapper: 'false' + body: !!binary |- + PGV4ZWN1dGlvbnMgY291bnQ9JzEnPgogIDxleGVjdXRpb24gaWQ9Jzk0NicgaHJlZj0naHR0cDovL2RpZ25hbjo0NDQwL2V4ZWN1dGlvbi9mb2xsb3cvOTQ2JyBzdGF0dXM9J3J1bm5pbmcnIHByb2plY3Q9J3Rlc3QnPgogICAgPHVzZXI+YWRtaW48L3VzZXI+CiAgICA8ZGF0ZS1zdGFydGVkIHVuaXh0aW1lPScxNDE1NjQ4MjUxMTg0Jz4yMDE0LTExLTEwVDE5OjM3OjMxWjwvZGF0ZS1zdGFydGVkPgogICAgPGRlc2NyaXB0aW9uPmVjaG8gdGVzdCB0cmlnZ2VyX2FkaG9jX2NvbW1hbmQ8L2Rlc2NyaXB0aW9uPgogICAgPGFyZ3N0cmluZyAvPgogIDwvZXhlY3V0aW9uPgo8L2V4ZWN1dGlvbnM+ diff --git a/src/test/resources/betamax/tapes/trigger_adhoc_command_v11_buggy.yaml b/src/test/resources/betamax/tapes/trigger_adhoc_command_v11_buggy.yaml new file mode 100644 index 0000000..5f29a07 --- /dev/null +++ b/src/test/resources/betamax/tapes/trigger_adhoc_command_v11_buggy.yaml @@ -0,0 +1,42 @@ +!tape +name: trigger_adhoc_command_v11_buggy +interactions: +- recorded: 2014-11-10T19:18:37.071Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/run/command?project=test&exec=echo+test+trigger_adhoc_command + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: application/xml;charset=UTF-8 + Expires: Thu, 01 Jan 1970 00:00:00 GMT + Server: Jetty(7.6.0.v20120127) + Set-Cookie: JSESSIONID=jjryjdfuxtdw1808gclmb7uuj;Path=/ + X-Rundeck-API-Version: '12' + X-Rundeck-API-XML-Response-Wrapper: 'false' + body: !!binary |- + PGV4ZWN1dGlvbiBpZD0nOTQ1JyAvPg== +- recorded: 2014-11-10T19:18:37.444Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/execution/945 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-10T19:18:36Z\n\ + \ echo test trigger_adhoc_command\n \n \n \n" diff --git a/src/test/resources/betamax/tapes/trigger_adhoc_script_v11.yaml b/src/test/resources/betamax/tapes/trigger_adhoc_script_v11.yaml new file mode 100644 index 0000000..8b133c0 --- /dev/null +++ b/src/test/resources/betamax/tapes/trigger_adhoc_script_v11.yaml @@ -0,0 +1,45 @@ +!tape +name: trigger_adhoc_script_v11 +interactions: +- recorded: 2014-11-10T20:04:36.573Z + request: + method: POST + uri: http://rundeck.local:4440/api/11/run/script?project=test + headers: + Accept: text/xml + Content-Type: multipart/form-data; boundary=W2S1I8XOmvOWsdnLEHprcw3N6cQveJEm_aV17Oz + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + Transfer-Encoding: chunked + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: application/xml;charset=UTF-8 + Expires: Thu, 01 Jan 1970 00:00:00 GMT + Server: Jetty(7.6.0.v20120127) + Set-Cookie: JSESSIONID=18uoooauscne2eqtuq466djm;Path=/ + X-Rundeck-API-Version: '12' + X-Rundeck-API-XML-Response-Wrapper: 'false' + body: !!binary |- + PGV4ZWN1dGlvbiBpZD0nOTQ4JyAvPg== +- recorded: 2014-11-10T20:04:36.876Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/execution/948 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: application/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + X-Rundeck-API-XML-Response-Wrapper: 'false' + body: !!binary |- + PGV4ZWN1dGlvbnMgY291bnQ9JzEnPgogIDxleGVjdXRpb24gaWQ9Jzk0OCcgaHJlZj0naHR0cDovL2RpZ25hbjo0NDQwL2V4ZWN1dGlvbi9mb2xsb3cvOTQ4JyBzdGF0dXM9J3J1bm5pbmcnIHByb2plY3Q9J3Rlc3QnPgogICAgPHVzZXI+YWRtaW48L3VzZXI+CiAgICA8ZGF0ZS1zdGFydGVkIHVuaXh0aW1lPScxNDE1NjQ5ODc2MzA1Jz4yMDE0LTExLTEwVDIwOjA0OjM2WjwvZGF0ZS1zdGFydGVkPgogICAgPGRlc2NyaXB0aW9uPiMhL2Jpbi9iYXNoCmVjaG8gdGVzdCB0cmlnZ2VyX2FkaG9jX3NjcmlwdAo8L2Rlc2NyaXB0aW9uPgogICAgPGFyZ3N0cmluZyAvPgogIDwvZXhlY3V0aW9uPgo8L2V4ZWN1dGlvbnM+ diff --git a/src/test/resources/betamax/tapes/trigger_adhoc_script_v11_buggy.yaml b/src/test/resources/betamax/tapes/trigger_adhoc_script_v11_buggy.yaml new file mode 100644 index 0000000..970ba9a --- /dev/null +++ b/src/test/resources/betamax/tapes/trigger_adhoc_script_v11_buggy.yaml @@ -0,0 +1,44 @@ +!tape +name: trigger_adhoc_script_v11_buggy +interactions: +- recorded: 2014-11-10T19:54:03.631Z + request: + method: POST + uri: http://rundeck.local:4440/api/11/run/script?project=test + headers: + Accept: text/xml + Content-Type: multipart/form-data; boundary=7ijcD_EYqXFXKLau3Bg9Oy0PIqf37Vn + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + Transfer-Encoding: chunked + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: application/xml;charset=UTF-8 + Expires: Thu, 01 Jan 1970 00:00:00 GMT + Server: Jetty(7.6.0.v20120127) + Set-Cookie: JSESSIONID=z5e76c45acya1h081pryh4avz;Path=/ + X-Rundeck-API-Version: '12' + X-Rundeck-API-XML-Response-Wrapper: 'false' + body: !!binary |- + PGV4ZWN1dGlvbiBpZD0nOTQ3JyAvPg== +- recorded: 2014-11-10T19:54:03.770Z + request: + method: GET + uri: http://rundeck.local:4440/api/11/execution/947 + headers: + Accept: text/xml + Host: rundeck.local:4440 + Proxy-Connection: Keep-Alive + User-Agent: RunDeck API Java Client 11 + X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s + response: + status: 200 + headers: + Content-Type: text/xml;charset=UTF-8 + Server: Jetty(7.6.0.v20120127) + X-Rundeck-API-Version: '12' + body: "\n \n \n admin\n 2014-11-10T19:54:03Z\n\ + \ #!/bin/bash\necho test trigger_adhoc_script\n\n \n \n \n"