Skip to content

Commit 4b93dc5

Browse files
marcushollo-liver
andauthored
Provide response from tms file upload also in case of rc outside 2xx (#1297)
* Provide response from tms file upload also in case of return codes outside 2xx * Update src/com/sap/piper/integration/TransportManagementService.groovy Co-Authored-By: Oliver Feldmann <[email protected]> * Update src/com/sap/piper/integration/TransportManagementService.groovy Co-Authored-By: Oliver Feldmann <[email protected]> * consider re-running in verbose mode only if we are not in verbose mode * Add missing script reference when calling error * avoid curl --fail in order to get also a response in case of 4xx 5xx * add missing write-out * --output instead of -o * fix syntax errors * fix codeclimat issue * fix unit tests /1 * Adjust unit tests * More unit tests * Use other texts in verbose mode and non verbose mode in case of a failure in order to avoid issue with hanging log messages surviving a test case (... should not be the case). For the non verbose mode we check the http response code since there is not message we can check. * Now with the full comment explaining the 418 * Provide different responses for verbose and non-verbose mode in order to distinguish the cases Co-authored-by: Oliver Feldmann <[email protected]>
1 parent ded6152 commit 4b93dc5

File tree

2 files changed

+85
-17
lines changed

2 files changed

+85
-17
lines changed

src/com/sap/piper/integration/TransportManagementService.groovy

+34-8
Original file line numberDiff line numberDiff line change
@@ -73,20 +73,46 @@ class TransportManagementService implements Serializable {
7373

7474
def proxy = config.proxy ? config.proxy : script.env.HTTP_PROXY
7575

76-
script.sh """#!/bin/sh -e
77-
curl ${proxy ? '--proxy ' + proxy + ' ' : ''} -H 'Authorization: Bearer ${token}' -F 'file=@${file}' -F 'namedUser=${namedUser}' -o responseFileUpload.txt --fail '${url}/v2/files/upload'
78-
"""
76+
def responseFileUpload = 'responseFileUpload.txt'
7977

80-
def responseContent = script.readFile("responseFileUpload.txt")
78+
def responseContent
8179

82-
if (config.verbose) {
83-
echo("${responseContent}")
80+
def responseCode = script.sh returnStdout: true,
81+
script:"""|#!/bin/sh -e
82+
| curl ${proxy ? '--proxy ' + proxy + ' ' : ''} \\
83+
| --write-out '%{response_code}' \\
84+
| -H 'Authorization: Bearer ${token}' \\
85+
| -F 'file=@${file}' \\
86+
| -F 'namedUser=${namedUser}' \\
87+
| --output ${responseFileUpload} \\
88+
| '${url}/v2/files/upload'""".stripMargin()
89+
90+
91+
def responseBody = 'n/a'
92+
93+
boolean gotResponse = script.fileExists(responseFileUpload)
94+
95+
if(gotResponse) {
96+
responseBody = script.readFile(responseFileUpload)
97+
if(config.verbose) {
98+
echo("Response body: ${responseBody}")
99+
}
84100
}
85101

86-
echo("File upload successful.")
102+
def HTTP_CREATED = '201'
87103

88-
return jsonUtils.jsonStringToGroovyObject(responseContent)
104+
if (responseCode != HTTP_CREATED) {
105+
def message = "Unexpected response code received from file upload (${responseCode}). ${HTTP_CREATED} expected."
106+
echo "${message} Response body: ${responseBody}"
107+
script.error message
108+
}
89109

110+
echo("File upload successful.")
111+
112+
if (! gotResponse) {
113+
script.error "Cannot provide upload file response."
114+
}
115+
return jsonUtils.jsonStringToGroovyObject(responseBody)
90116
}
91117

92118

test/groovy/com/sap/piper/integration/TransportManagementServiceTest.groovy

+51-9
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ class TransportManagementServiceTest extends BasePiperTest {
1515
private ExpectedException thrown = ExpectedException.none()
1616
private JenkinsShellCallRule shellRule = new JenkinsShellCallRule(this)
1717
private JenkinsLoggingRule loggingRule = new JenkinsLoggingRule(this)
18+
private JenkinsReadFileRule readFileRule = new JenkinsReadFileRule(this, 'test/resources/TransportManagementService')
19+
private JenkinsFileExistsRule fileExistsRule = new JenkinsFileExistsRule(this, ['responseFileUpload.txt'])
1820

1921
@Rule
2022
public RuleChain rules = Rules
@@ -23,7 +25,8 @@ class TransportManagementServiceTest extends BasePiperTest {
2325
.around(new JenkinsReadJsonRule(this))
2426
.around(shellRule)
2527
.around(loggingRule)
26-
.around(new JenkinsReadFileRule(this, 'test/resources/TransportManagementService'))
28+
.around(readFileRule)
29+
.around(fileExistsRule)
2730
.around(thrown)
2831

2932
@Test
@@ -77,33 +80,70 @@ class TransportManagementServiceTest extends BasePiperTest {
7780
def file = 'myFile.mtar'
7881
def namedUser = 'myUser'
7982

83+
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX,'.*curl.*', '201')
84+
8085
def tms = new TransportManagementService(nullScript, [:])
8186
def responseDetails = tms.uploadFile(url, token, file, namedUser)
8287

83-
def oAuthShellCall = shellRule.shell[0]
88+
// replace needed since the curl command is spread over several lines.
89+
def oAuthShellCall = shellRule.shell[0].replaceAll('\\\\ ', '')
8490

8591
assertThat(loggingRule.log, containsString("[TransportManagementService] File upload started."))
8692
assertThat(loggingRule.log, containsString("[TransportManagementService] File upload successful."))
8793
assertThat(oAuthShellCall, startsWith("#!/bin/sh -e "))
88-
assertThat(oAuthShellCall, endsWith("curl -H 'Authorization: Bearer ${token}' -F 'file=@${file}' -F 'namedUser=${namedUser}' -o responseFileUpload.txt --fail '${url}/v2/files/upload'"))
94+
assertThat(oAuthShellCall, endsWith("curl --write-out '%{response_code}' -H 'Authorization: Bearer ${token}' -F 'file=@${file}' -F 'namedUser=${namedUser}' --output responseFileUpload.txt '${url}/v2/files/upload'"))
8995
assertThat(responseDetails, hasEntry("fileId", 1234))
9096
}
9197

92-
@Ignore
93-
void uploadFile__withHttpErrorResponse__throwsError() {
98+
@Test
99+
void uploadFile__verboseMode__withHttpErrorResponse__throwsError() {
94100

95101
def url = 'http://dummy.com/oauth'
96102
def token = 'myWrongToken'
97103
def file = 'myFile.mtar'
98104
def namedUser = 'myUser'
99105

100-
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, ".* curl .*", {throw new AbortException()})
106+
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, ".* curl .*", '400')
107+
108+
readFileRule.files << [ 'responseFileUpload.txt': 'Something went wrong during file upload (WE ARE IN VERBOSE MODE)']
101109

102110
thrown.expect(AbortException.class)
111+
thrown.expectMessage('Unexpected response code received from file upload (400). 201 expected')
103112

104-
def tms = new TransportManagementService(nullScript, [:])
105-
tms.uploadFile(url, token, file, namedUser)
113+
loggingRule.expect('[TransportManagementService] URL: \'http://dummy.com/oauth\', File: \'myFile.mtar\'')
114+
loggingRule.expect('[TransportManagementService] Response body: Something went wrong during file upload (WE ARE IN VERBOSE MODE)')
115+
116+
// The log entries which are present in non verbose mode must be present in verbose mode also, of course
117+
loggingRule.expect('[TransportManagementService] File upload started.')
118+
loggingRule.expect('[TransportManagementService] Unexpected response code received from file upload (400). 201 expected. Response body: Something went wrong during file upload')
119+
120+
new TransportManagementService(nullScript, [verbose:true])
121+
.uploadFile(url, token, file, namedUser)
122+
}
123+
124+
@Test
125+
void uploadFile__NonVerboseMode__withHttpErrorResponse__throwsError() {
126+
127+
def url = 'http://dummy.com/oauth'
128+
def token = 'myWrongToken'
129+
def file = 'myFile.mtar'
130+
def namedUser = 'myUser'
131+
132+
// 418 (tea-pot)? Other than 400 which is used in verbose mode in order to be sure that we don't mix up
133+
// with any details from the other test for the verbose mode. The log message below (Unexpected response code ...)
134+
// reflects that 418 instead of 400.
135+
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, ".* curl .*", '418')
136+
137+
readFileRule.files << [ 'responseFileUpload.txt': 'Something went wrong during file upload. WE ARE IN NON VERBOSE MODE.']
138+
139+
thrown.expect(AbortException.class)
140+
thrown.expectMessage('Unexpected response code received from file upload (418). 201 expected')
141+
142+
loggingRule.expect('[TransportManagementService] File upload started.')
143+
loggingRule.expect('[TransportManagementService] Unexpected response code received from file upload (418). 201 expected. Response body: Something went wrong during file upload. WE ARE IN NON VERBOSE MODE.')
106144

145+
new TransportManagementService(nullScript, [verbose:false])
146+
.uploadFile(url, token, file, namedUser)
107147
}
108148

109149
@Test
@@ -114,7 +154,9 @@ class TransportManagementServiceTest extends BasePiperTest {
114154
def file = 'myFile.mtar'
115155
def namedUser = 'myUser'
116156

117-
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, ".* curl .*", '200')
157+
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, ".* curl .*", '201')
158+
fileExistsRule.existingFiles.add('responseFileUpload.txt')
159+
readFileRule.files.put('responseFileUpload.txt', '{"fileId": 1234}')
118160

119161
def tms = new TransportManagementService(nullScript, [verbose: true])
120162
tms.uploadFile(url, token, file, namedUser)

0 commit comments

Comments
 (0)