Fix GET HTTP 202 status without Location
When a GET request is performed on an asynchronous operation task monitor URI, the iDRAC service can correctly return the HTTP '202 Accepted' status code without a 'Location' header. [1] This has been observed while querying the status of the long-running OEM Server Configuration Profile (SCP) import and export system configuration operations. [2] sushy-oem-idrac has incorrectly required the 'Location' header to continue to query the status of the operation, and determine when it has completed and whether it succeeded. This fixes that by reusing the URI provided in the 'Location' header of the response to a previous request, instead of failing. [1] http://redfish.dmtf.org/schemas/DSP0266_1.11.0.html#asynchronous-operations [2] Pushkala Iyer et al., "Server Cloning with Server Configuration Profiles", (Dell Inc., version 1.1, July 2016), https://downloads.dell.com/solutions/dell-management-solution-resources/Server Cloning with Server Configuration Profiles 1_1 Final.pdf. Co-Authored-By: Derek Higgins <derekh@redhat.com> Story: 2007640 Task: 39697 Change-Id: I07eef4bab7285d2c454a6112a43b0725e8ee5a09
This commit is contained in:
parent
71050eaca6
commit
9915d8e16d
@ -42,8 +42,9 @@ def http_call(conn, method, *args, **kwargs):
|
||||
LOG.debug('Finished HTTP %s with args %s %s, response is '
|
||||
'%d', method, args or '', kwargs, response.status_code)
|
||||
|
||||
location = None
|
||||
while response.status_code == 202:
|
||||
location = response.headers.get('location')
|
||||
location = response.headers.get('location', location)
|
||||
if not location:
|
||||
raise sushy.exceptions.ExtensionError(
|
||||
error='Response %d to HTTP %s with args %s, kwargs %s '
|
||||
|
55
sushy_oem_idrac/tests/unit/test_asynchronous.py
Normal file
55
sushy_oem_idrac/tests/unit/test_asynchronous.py
Normal file
@ -0,0 +1,55 @@
|
||||
# Copyright (c) 2020 Dell Inc. or its subsidiaries.
|
||||
#
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from unittest import mock
|
||||
|
||||
from oslotest.base import BaseTestCase
|
||||
import sushy
|
||||
|
||||
from sushy_oem_idrac.asynchronous import http_call
|
||||
|
||||
|
||||
class AsychronousTestCase(BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(AsychronousTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
|
||||
def test_http_call_post_accepted(self):
|
||||
mock_post_response = self.conn.post.return_value
|
||||
mock_post_response.status_code = 202
|
||||
mock_post_response.headers.get.return_value = '1'
|
||||
|
||||
mock_get_202_response = mock.Mock()
|
||||
mock_get_202_response.status_code = 202
|
||||
mock_get_202_response.headers.get.return_value = '1'
|
||||
|
||||
mock_get_200_response = mock.Mock()
|
||||
mock_get_200_response.status_code = 200
|
||||
|
||||
self.conn.get.side_effect = [
|
||||
mock_get_202_response, mock_get_200_response]
|
||||
|
||||
resp = http_call(self.conn, 'POST')
|
||||
self.assertIs(resp, mock_get_200_response)
|
||||
|
||||
def test_http_call_post_accepted_no_location(self):
|
||||
mock_response = self.conn.post.return_value
|
||||
mock_response.status_code = 202
|
||||
mock_response.headers.get.return_value = None
|
||||
|
||||
self.assertRaises(sushy.exceptions.ExtensionError,
|
||||
http_call, self.conn, 'POST')
|
Loading…
x
Reference in New Issue
Block a user