Skip to content

Commit

Permalink
Move Re-driving requests from c code to python
Browse files Browse the repository at this point in the history
Move redriving requests from c layer to python layer

Signed-off-by: Elijah Swift <elijah.swift@ibm.com>
  • Loading branch information
ElijahSwiftIBM committed Feb 29, 2024
1 parent 5b7670e commit e62bdea
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 50 deletions.
42 changes: 3 additions & 39 deletions pyracf/common/irrsmo00.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ static PyObject *call_irrsmo00(PyObject *self, PyObject *args, PyObject *kwargs)
return NULL;
}

PyObject * full_result;
char work_area[1024];
unsigned char req_handle[64] = {0};
running_userid_t running_userid_struct = {running_userid_length, {0}};
Expand Down Expand Up @@ -87,41 +86,6 @@ static PyObject *call_irrsmo00(PyObject *self, PyObject *args, PyObject *kwargs)
&result_len,
result_buffer);

// Use a PyList Structure to accumulate "bytes" objects of result_buffers
full_result = PyList_New(1);
PyList_SetItem(full_result, 0, Py_BuildValue("y#", result_buffer, result_len));

if ((saf_rc == 8) && (racf_rc == 4000) && (racf_rsn < 100000000)){
free(result_buffer);
result_len = racf_rsn;
result_buffer = malloc(result_len);
memset(result_buffer, 0, result_len);

// Call IRRSMO64 Again with the appropriate buffer size
IRRSMO64(
work_area,
alet,
&saf_rc,
alet,
&racf_rc,
alet,
&racf_rsn,
num_parms,
fn,
irrsmo00_options,
request_xml_length,
request_xml,
req_handle,
running_userid_struct,
acee,
&result_len,
result_buffer);

PyList_Append(full_result, Py_BuildValue("y#", result_buffer, result_len));
}

free(result_buffer);

// https://docs.python.org/3/c-api/arg.html#c.Py_BuildValue
//
// According to the Python 3 C API documentation:
Expand Down Expand Up @@ -159,8 +123,8 @@ static PyObject *call_irrsmo00(PyObject *self, PyObject *args, PyObject *kwargs)
// Py_BuildValue() will return a Tuple.

return Py_BuildValue(
"{s:O,s:[B,B,B]}",
"resultBuffers", full_result,
"{s:y#,s:[B,B,B]}",
"resultBuffer", result_buffer, result_len,
"returnCodes", saf_rc, racf_rc, racf_rsn);
}

Expand All @@ -172,7 +136,7 @@ static char call_irrsmo00_docs[] =
" irrsmo00_options: uint,\n"
" running_userid: bytes,\n"
" running_userid_length: uint,\n"
") -> Dict{ resultBuffers: List[bytes], returnCodes: List[int,int,int] }:\n"
") -> Dict{ resultBuffer: bytes, returnCodes: List[int,int,int] }:\n"
"# Returns an XML result string and return and reason "
"codes from the IRRSMO00 RACF Callable Service.\n";

Expand Down
17 changes: 16 additions & 1 deletion pyracf/common/irrsmo00.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,25 @@ def call_racf(
running_userid=running_userid,
running_userid_len=len(running_userid),
)
if (
(result["returnCodes"][0] == 8)
and (result["returnCodes"][1] == 4000)
and (result["returnCodes"][2] < 100000000)
):
first_result_buffer = result["resultBuffer"]
result = call_irrsmo00(
request_xml=request_xml,
request_xml_len=len(request_xml),
result_buffer_size=result["returnCodes"][2],
irrsmo00_options=irrsmo00_options,
running_userid=running_userid,
running_userid_len=len(running_userid),
)
result["resultBuffer"] = first_result_buffer + result["resultBuffer"]
# Preserve raw result XML just in case we need to create a dump.
# If the decoded result XML cannot be parsed with the XML parser,
# a dump may need to be taken to aid in problem determination.
self.__raw_result_xml = b"".join(result["resultBuffers"])
self.__raw_result_xml = result["resultBuffer"]
# Replace any null bytes in the result XML with spaces.
result_xml = self.__null_byte_fix(self.__raw_result_xml)
# 'irrsmo00.c' returns a raw unmodified bytes object containing a copy
Expand Down
39 changes: 29 additions & 10 deletions tests/common/test_irrsmo00_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def test_irrsmo00_null_byte_fix(
])
# fmt: on
call_irrsmo00_wrapper_mock.return_value = {
"resultBuffers": [xml_containing_null_bytes],
"resultBuffer": xml_containing_null_bytes,
"returnCodes": [0, 0, 0],
}
self.assertEqual(
Expand All @@ -71,7 +71,7 @@ def test_irrsmo00_empty_result(
):
# Simulate failure due to incomplete 'IRR.IRRSMO00.PRECHECK' setup
call_irrsmo00_wrapper_mock.return_value = {
"resultBuffers": [bytes([0 for i in range(256)])],
"resultBuffer": bytes([0 for i in range(256)]),
"returnCodes": [8, 200, 16],
}
self.assertEqual(self.irrsmo00.call_racf(b""), [8, 200, 16])
Expand All @@ -82,20 +82,39 @@ def test_irrsmo00_result_buffer_full_failure(
):
# Simulate scenario where result buffer is too small.
call_irrsmo00_wrapper_mock.return_value = {
"resultBuffers": [self.good_xml[:32]],
"returnCodes": [8, 4000, 32],
"resultBuffer": self.good_xml[:32],
"returnCodes": [8, 4000, 100000000],
}
self.assertEqual(
self.irrsmo00.call_racf(b""), self.good_xml.decode("cp1047")[:32]
)

# def test_irrsmo00_result_buffer_full_redrive(
# self,
# call_irrsmo00_wrapper_mock: Mock,
# ):
# # Simulate scenario where result buffer is too small.
# call_irrsmo00_wrapper_mock.side_effect = [
# {
# "resultBuffer": self.good_xml[:32],
# "returnCodes": [8, 4000, 32],
# },
# {
# "resultBuffer": self.good_xml[32:],
# "returnCodes": [0, 0, 0],
# },
# ]
# self.assertEqual(
# self.irrsmo00.call_racf(b""), self.good_xml.decode("cp1047")
# )

def test_irrsmo00_result_buffer_full_success(
self,
call_irrsmo00_wrapper_mock: Mock,
):
# Simulate scenario where result buffer is exactly the right size.
call_irrsmo00_wrapper_mock.return_value = {
"resultBuffers": [self.good_xml[: self.good_xml_null_terminator_index]],
"resultBuffer": self.good_xml[: self.good_xml_null_terminator_index],
"returnCodes": [0, 0, 0],
}
self.assertEqual(
Expand All @@ -105,7 +124,7 @@ def test_irrsmo00_result_buffer_full_success(

def test_irrsmo00_normal_result(self, call_irrsmo00_wrapper_mock: Mock):
call_irrsmo00_wrapper_mock.return_value = {
"resultBuffers": [self.good_xml],
"resultBuffer": self.good_xml,
"returnCodes": [0, 0, 0],
}
self.assertEqual(
Expand All @@ -118,7 +137,7 @@ def test_irrsmo00_normal_result(self, call_irrsmo00_wrapper_mock: Mock):
# ============================================================================
def test_irrsmo00_minimum_arguments(self, call_irrsmo00_wrapper_mock: Mock):
call_irrsmo00_wrapper_mock.return_value = {
"resultBuffers": [self.good_xml],
"resultBuffer": self.good_xml,
"returnCodes": [0, 0, 0],
}
self.irrsmo00.call_racf(b"some bytes")
Expand All @@ -133,7 +152,7 @@ def test_irrsmo00_minimum_arguments(self, call_irrsmo00_wrapper_mock: Mock):

def test_irrsmo00_with_precheck_set_to_true(self, call_irrsmo00_wrapper_mock: Mock):
call_irrsmo00_wrapper_mock.return_value = {
"resultBuffers": [self.good_xml],
"resultBuffer": self.good_xml,
"returnCodes": [0, 0, 0],
}
self.irrsmo00.call_racf(b"some bytes", precheck=True)
Expand All @@ -148,7 +167,7 @@ def test_irrsmo00_with_precheck_set_to_true(self, call_irrsmo00_wrapper_mock: Mo

def test_irrsmo00_with_run_as_userid_set(self, call_irrsmo00_wrapper_mock: Mock):
call_irrsmo00_wrapper_mock.return_value = {
"resultBuffers": [self.good_xml],
"resultBuffer": self.good_xml,
"returnCodes": [0, 0, 0],
}
self.irrsmo00.call_racf(b"some bytes", run_as_userid="KRABS")
Expand All @@ -165,7 +184,7 @@ def test_irrsmo00_with_custom_result_buffer_size(
self, call_irrsmo00_wrapper_mock: Mock
):
call_irrsmo00_wrapper_mock.return_value = {
"resultBuffers": [self.good_xml],
"resultBuffer": self.good_xml,
"returnCodes": [0, 0, 0],
}
irrsmo00 = IRRSMO00(result_buffer_size=32768)
Expand Down

0 comments on commit e62bdea

Please sign in to comment.