-
-
Notifications
You must be signed in to change notification settings - Fork 33.6k
gh-136336: add tests for PySys_Audit() and PySys_AuditTuple() #136337
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -12,11 +12,6 @@ | |||||||||||||||
| NULL = None | ||||||||||||||||
|
|
||||||||||||||||
| class CAPITest(unittest.TestCase): | ||||||||||||||||
| # TODO: Test the following functions: | ||||||||||||||||
| # | ||||||||||||||||
| # PySys_Audit() | ||||||||||||||||
| # PySys_AuditTuple() | ||||||||||||||||
|
|
||||||||||||||||
| maxDiff = None | ||||||||||||||||
|
|
||||||||||||||||
| @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') | ||||||||||||||||
|
|
@@ -211,6 +206,142 @@ def test_sys_writestderr(self): | |||||||||||||||
| # Test PySys_WriteStderr() | ||||||||||||||||
| self._test_sys_writestream('PySys_WriteStderr', 'stderr') | ||||||||||||||||
|
|
||||||||||||||||
| @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') | ||||||||||||||||
| def test_sys_audit(self): | ||||||||||||||||
| sys_audit = _testlimitedcapi.sys_audit | ||||||||||||||||
|
|
||||||||||||||||
| audit_events = [] | ||||||||||||||||
| def audit_hook(event, args): | ||||||||||||||||
| audit_events.append((event, args)) | ||||||||||||||||
| return None | ||||||||||||||||
|
|
||||||||||||||||
| import sys | ||||||||||||||||
| sys.addaudithook(audit_hook) | ||||||||||||||||
|
|
||||||||||||||||
| try: | ||||||||||||||||
| result = sys_audit("cpython.run_command", "") | ||||||||||||||||
| self.assertEqual(result, 0) | ||||||||||||||||
| self.assertEqual(len(audit_events), 1) | ||||||||||||||||
| self.assertEqual(audit_events[-1][0], "cpython.run_command") | ||||||||||||||||
| self.assertEqual(audit_events[-1][1], ()) | ||||||||||||||||
|
|
||||||||||||||||
| result = sys_audit("open", "OOO", "test.txt", "r", 0) | ||||||||||||||||
| self.assertEqual(result, 0) | ||||||||||||||||
| self.assertEqual(len(audit_events), 2) | ||||||||||||||||
| self.assertEqual(audit_events[-1][0], "open") | ||||||||||||||||
| self.assertEqual(len(audit_events[-1][1]), 3) | ||||||||||||||||
| self.assertEqual(audit_events[-1][1][0], "test.txt") | ||||||||||||||||
| self.assertEqual(audit_events[-1][1][1], "r") | ||||||||||||||||
| self.assertEqual(audit_events[-1][1][2], 0) | ||||||||||||||||
|
|
||||||||||||||||
| test_dict = {"key": "value"} | ||||||||||||||||
| test_list = [1, 2, 3] | ||||||||||||||||
| result = sys_audit("test.objects", "OO", test_dict, test_list) | ||||||||||||||||
| self.assertEqual(result, 0) | ||||||||||||||||
| self.assertEqual(len(audit_events), 3) | ||||||||||||||||
| self.assertEqual(audit_events[-1][0], "test.objects") | ||||||||||||||||
| self.assertEqual(audit_events[-1][1][0], test_dict) | ||||||||||||||||
| self.assertEqual(audit_events[-1][1][1], test_list) | ||||||||||||||||
|
|
||||||||||||||||
| result = sys_audit("test.mixed_types", "OOO", "string", 42, 123456789) | ||||||||||||||||
| self.assertEqual(result, 0) | ||||||||||||||||
| self.assertEqual(len(audit_events), 4) | ||||||||||||||||
| self.assertEqual(audit_events[-1][0], "test.mixed_types") | ||||||||||||||||
| self.assertEqual(audit_events[-1][1][0], "string") | ||||||||||||||||
| self.assertEqual(audit_events[-1][1][1], 42) | ||||||||||||||||
| self.assertEqual(audit_events[-1][1][2], 123456789) | ||||||||||||||||
|
|
||||||||||||||||
| finally: | ||||||||||||||||
|
||||||||||||||||
| sys.audit_hooks = [] | ||||||||||||||||
|
|
||||||||||||||||
| result = sys_audit("cpython.run_file", "") | ||||||||||||||||
| self.assertEqual(result, 0) | ||||||||||||||||
|
|
||||||||||||||||
| result = sys_audit("os.chdir", "(O)", "/tmp") | ||||||||||||||||
| self.assertEqual(result, 0) | ||||||||||||||||
|
|
||||||||||||||||
| result = sys_audit("ctypes.dlopen", "O", "libc.so.6") | ||||||||||||||||
| self.assertEqual(result, 0) | ||||||||||||||||
|
|
||||||||||||||||
| self.assertRaises(TypeError, sys_audit, 123, "O", "arg") | ||||||||||||||||
| self.assertRaises(TypeError, sys_audit, None, "O", "arg") | ||||||||||||||||
| self.assertRaises(TypeError, sys_audit, ["not", "a", "string"], "O", "arg") | ||||||||||||||||
|
|
||||||||||||||||
| self.assertRaises(TypeError, sys_audit, "test.event", 456, "arg") | ||||||||||||||||
| self.assertRaises(TypeError, sys_audit, "test.event", None, "arg") | ||||||||||||||||
| self.assertRaises(TypeError, sys_audit, "test.event", {"format": "string"}, "arg") | ||||||||||||||||
|
|
||||||||||||||||
| @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') | ||||||||||||||||
| def test_sys_audittuple(self): | ||||||||||||||||
| sys_audittuple = _testlimitedcapi.sys_audittuple | ||||||||||||||||
|
|
||||||||||||||||
| # Test with audit hook to verify internal behavior | ||||||||||||||||
|
||||||||||||||||
| sys_audittuple = _testlimitedcapi.sys_audittuple | |
| # Test with audit hook to verify internal behavior | |
| # Test PySys_AuditTuple() | |
| sys_audittuple = _testlimitedcapi.sys_audittuple | |
| # Test with audit hook to verify internal behavior |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is redundant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return None |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Import it at the top level.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are too many tests which don't add much to coverage. You only need one test with non-empty tuple, one test with NULL as the second argument, one test with non-tuple as the second argument, and few tests for the event argument: non-ASCII string, non-UTF-8 bytes string, NULL.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add also test for sys_audittuple(NULL, (1,)). If it crashes, just add a comment, like in other tests above.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, this does not work. There is no way to remove the audit hook. This is why these functions remained untested -- because the only way to test them is to use a subprocess. Look like other audit tests are implemented.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do these test add in comparison with the above tests?
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests don't test PySys_AuditTuple. They test the wrapper.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ | |
| #endif | ||
| #include "parts.h" | ||
| #include "util.h" | ||
| #include "audit.h" | ||
|
|
||
|
|
||
| static PyObject * | ||
|
|
@@ -106,6 +107,48 @@ sys_getxoptions(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(ignored)) | |
| return Py_XNewRef(result); | ||
| } | ||
|
|
||
| static PyObject * | ||
| sys_audit(PyObject *Py_UNUSED(module), PyObject *args) | ||
| { | ||
| const char *event; | ||
| const char *argFormat; | ||
| PyObject *arg1 = NULL, *arg2 = NULL, *arg3 = NULL; | ||
|
|
||
| if (!PyArg_ParseTuple(args, "ss|OOO", &event, &argFormat, &arg1, &arg2, &arg3)) { | ||
|
||
| return NULL; | ||
| } | ||
|
|
||
| int result; | ||
| if (arg1 == NULL) { | ||
| result = PySys_Audit(event, argFormat); | ||
| } else if (arg2 == NULL) { | ||
| result = PySys_Audit(event, argFormat, arg1); | ||
| } else if (arg3 == NULL) { | ||
| result = PySys_Audit(event, argFormat, arg1, arg2); | ||
| } else { | ||
| result = PySys_Audit(event, argFormat, arg1, arg2, arg3); | ||
| } | ||
|
|
||
| RETURN_INT(result); | ||
| } | ||
|
|
||
| static PyObject * | ||
| sys_audittuple(PyObject *Py_UNUSED(module), PyObject *args) | ||
| { | ||
| const char *event; | ||
| PyObject *tuple_args; | ||
|
|
||
| if (!PyArg_ParseTuple(args, "sO", &event, &tuple_args)) { | ||
|
||
| return NULL; | ||
| } | ||
|
|
||
| if (!PyTuple_Check(tuple_args)) { | ||
|
||
| PyErr_SetString(PyExc_TypeError, "second argument must be a tuple"); | ||
| return NULL; | ||
| } | ||
|
|
||
| RETURN_INT(PySys_AuditTuple(event, tuple_args)); | ||
| } | ||
|
|
||
| static PyMethodDef test_methods[] = { | ||
| {"sys_getattr", sys_getattr, METH_O}, | ||
|
|
@@ -115,6 +158,8 @@ static PyMethodDef test_methods[] = { | |
| {"sys_getobject", sys_getobject, METH_O}, | ||
| {"sys_setobject", sys_setobject, METH_VARARGS}, | ||
| {"sys_getxoptions", sys_getxoptions, METH_NOARGS}, | ||
| {"sys_audit", sys_audit, METH_VARARGS}, | ||
| {"sys_audittuple", sys_audittuple, METH_VARARGS}, | ||
| {NULL}, | ||
| }; | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.