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"