|  | 
| 12 | 12 | NULL = None | 
| 13 | 13 | 
 | 
| 14 | 14 | class CAPITest(unittest.TestCase): | 
| 15 |  | -    # TODO: Test the following functions: | 
| 16 |  | -    # | 
| 17 |  | -    #   PySys_Audit() | 
| 18 |  | -    #   PySys_AuditTuple() | 
| 19 |  | - | 
| 20 | 15 |     maxDiff = None | 
| 21 | 16 | 
 | 
| 22 | 17 |     @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') | 
| @@ -211,6 +206,142 @@ def test_sys_writestderr(self): | 
| 211 | 206 |         # Test PySys_WriteStderr() | 
| 212 | 207 |         self._test_sys_writestream('PySys_WriteStderr', 'stderr') | 
| 213 | 208 | 
 | 
|  | 209 | +    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') | 
|  | 210 | +    def test_sys_audit(self): | 
|  | 211 | +        sys_audit = _testlimitedcapi.sys_audit | 
|  | 212 | + | 
|  | 213 | +        audit_events = [] | 
|  | 214 | +        def audit_hook(event, args): | 
|  | 215 | +            audit_events.append((event, args)) | 
|  | 216 | +            return None | 
|  | 217 | + | 
|  | 218 | +        import sys | 
|  | 219 | +        sys.addaudithook(audit_hook) | 
|  | 220 | + | 
|  | 221 | +        try: | 
|  | 222 | +            result = sys_audit("cpython.run_command", "") | 
|  | 223 | +            self.assertEqual(result, 0) | 
|  | 224 | +            self.assertEqual(len(audit_events), 1) | 
|  | 225 | +            self.assertEqual(audit_events[-1][0], "cpython.run_command") | 
|  | 226 | +            self.assertEqual(audit_events[-1][1], ()) | 
|  | 227 | + | 
|  | 228 | +            result = sys_audit("open", "OOO", "test.txt", "r", 0) | 
|  | 229 | +            self.assertEqual(result, 0) | 
|  | 230 | +            self.assertEqual(len(audit_events), 2) | 
|  | 231 | +            self.assertEqual(audit_events[-1][0], "open") | 
|  | 232 | +            self.assertEqual(len(audit_events[-1][1]), 3) | 
|  | 233 | +            self.assertEqual(audit_events[-1][1][0], "test.txt") | 
|  | 234 | +            self.assertEqual(audit_events[-1][1][1], "r") | 
|  | 235 | +            self.assertEqual(audit_events[-1][1][2], 0) | 
|  | 236 | + | 
|  | 237 | +            test_dict = {"key": "value"} | 
|  | 238 | +            test_list = [1, 2, 3] | 
|  | 239 | +            result = sys_audit("test.objects", "OO", test_dict, test_list) | 
|  | 240 | +            self.assertEqual(result, 0) | 
|  | 241 | +            self.assertEqual(len(audit_events), 3) | 
|  | 242 | +            self.assertEqual(audit_events[-1][0], "test.objects") | 
|  | 243 | +            self.assertEqual(audit_events[-1][1][0], test_dict) | 
|  | 244 | +            self.assertEqual(audit_events[-1][1][1], test_list) | 
|  | 245 | + | 
|  | 246 | +            result = sys_audit("test.mixed_types", "OOO", "string", 42, 123456789) | 
|  | 247 | +            self.assertEqual(result, 0) | 
|  | 248 | +            self.assertEqual(len(audit_events), 4) | 
|  | 249 | +            self.assertEqual(audit_events[-1][0], "test.mixed_types") | 
|  | 250 | +            self.assertEqual(audit_events[-1][1][0], "string") | 
|  | 251 | +            self.assertEqual(audit_events[-1][1][1], 42) | 
|  | 252 | +            self.assertEqual(audit_events[-1][1][2], 123456789) | 
|  | 253 | + | 
|  | 254 | +        finally: | 
|  | 255 | +            sys.audit_hooks = [] | 
|  | 256 | + | 
|  | 257 | +        result = sys_audit("cpython.run_file", "") | 
|  | 258 | +        self.assertEqual(result, 0) | 
|  | 259 | + | 
|  | 260 | +        result = sys_audit("os.chdir", "(O)", "/tmp") | 
|  | 261 | +        self.assertEqual(result, 0) | 
|  | 262 | + | 
|  | 263 | +        result = sys_audit("ctypes.dlopen", "O", "libc.so.6") | 
|  | 264 | +        self.assertEqual(result, 0) | 
|  | 265 | + | 
|  | 266 | +        self.assertRaises(TypeError, sys_audit, 123, "O", "arg") | 
|  | 267 | +        self.assertRaises(TypeError, sys_audit, None, "O", "arg") | 
|  | 268 | +        self.assertRaises(TypeError, sys_audit, ["not", "a", "string"], "O", "arg") | 
|  | 269 | + | 
|  | 270 | +        self.assertRaises(TypeError, sys_audit, "test.event", 456, "arg") | 
|  | 271 | +        self.assertRaises(TypeError, sys_audit, "test.event", None, "arg") | 
|  | 272 | +        self.assertRaises(TypeError, sys_audit, "test.event", {"format": "string"}, "arg") | 
|  | 273 | + | 
|  | 274 | +    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') | 
|  | 275 | +    def test_sys_audittuple(self): | 
|  | 276 | +        sys_audittuple = _testlimitedcapi.sys_audittuple | 
|  | 277 | + | 
|  | 278 | +        # Test with audit hook to verify internal behavior | 
|  | 279 | +        audit_events = [] | 
|  | 280 | +        def audit_hook(event, args): | 
|  | 281 | +            audit_events.append((event, args)) | 
|  | 282 | +            return None | 
|  | 283 | + | 
|  | 284 | +        import sys | 
|  | 285 | +        sys.addaudithook(audit_hook) | 
|  | 286 | + | 
|  | 287 | +        try: | 
|  | 288 | +            result = sys_audittuple("cpython.run_command", ()) | 
|  | 289 | +            self.assertEqual(result, 0) | 
|  | 290 | +            self.assertEqual(len(audit_events), 1) | 
|  | 291 | +            self.assertEqual(audit_events[-1][0], "cpython.run_command") | 
|  | 292 | +            self.assertEqual(audit_events[-1][1], ()) | 
|  | 293 | + | 
|  | 294 | +            result = sys_audittuple("os.chdir", ("/tmp",)) | 
|  | 295 | +            self.assertEqual(result, 0) | 
|  | 296 | +            self.assertEqual(len(audit_events), 2) | 
|  | 297 | +            self.assertEqual(audit_events[-1][0], "os.chdir") | 
|  | 298 | +            self.assertEqual(audit_events[-1][1], ("/tmp",)) | 
|  | 299 | + | 
|  | 300 | +            result = sys_audittuple("open", ("test.txt", "r", 0)) | 
|  | 301 | +            self.assertEqual(result, 0) | 
|  | 302 | +            self.assertEqual(len(audit_events), 3) | 
|  | 303 | +            self.assertEqual(audit_events[-1][0], "open") | 
|  | 304 | +            self.assertEqual(audit_events[-1][1], ("test.txt", "r", 0)) | 
|  | 305 | + | 
|  | 306 | +            test_dict = {"key": "value"} | 
|  | 307 | +            test_list = [1, 2, 3] | 
|  | 308 | +            result = sys_audittuple("test.objects", (test_dict, test_list)) | 
|  | 309 | +            self.assertEqual(result, 0) | 
|  | 310 | +            self.assertEqual(len(audit_events), 4) | 
|  | 311 | +            self.assertEqual(audit_events[-1][0], "test.objects") | 
|  | 312 | +            self.assertEqual(audit_events[-1][1][0], test_dict) | 
|  | 313 | +            self.assertEqual(audit_events[-1][1][1], test_list) | 
|  | 314 | + | 
|  | 315 | +            result = sys_audittuple("test.complex", ("text", 3.14, True, None)) | 
|  | 316 | +            self.assertEqual(result, 0) | 
|  | 317 | +            self.assertEqual(len(audit_events), 5) | 
|  | 318 | +            self.assertEqual(audit_events[-1][0], "test.complex") | 
|  | 319 | +            self.assertEqual(audit_events[-1][1][0], "text") | 
|  | 320 | +            self.assertEqual(audit_events[-1][1][1], 3.14) | 
|  | 321 | +            self.assertEqual(audit_events[-1][1][2], True) | 
|  | 322 | +            self.assertEqual(audit_events[-1][1][3], None) | 
|  | 323 | + | 
|  | 324 | +        finally: | 
|  | 325 | +            sys.audit_hooks = [] | 
|  | 326 | + | 
|  | 327 | +        result = sys_audittuple("cpython.run_file", ()) | 
|  | 328 | +        self.assertEqual(result, 0) | 
|  | 329 | + | 
|  | 330 | +        result = sys_audittuple("ctypes.dlopen", ("libc.so.6",)) | 
|  | 331 | +        self.assertEqual(result, 0) | 
|  | 332 | + | 
|  | 333 | +        result = sys_audittuple("sqlite3.connect", ("test.db",)) | 
|  | 334 | +        self.assertEqual(result, 0) | 
|  | 335 | + | 
|  | 336 | +        self.assertRaises(TypeError, sys_audittuple, 123, ("arg",)) | 
|  | 337 | +        self.assertRaises(TypeError, sys_audittuple, None, ("arg",)) | 
|  | 338 | +        self.assertRaises(TypeError, sys_audittuple, ["not", "a", "string"], ("arg",)) | 
|  | 339 | + | 
|  | 340 | +        self.assertRaises(TypeError, sys_audittuple, "test.event", "not_a_tuple") | 
|  | 341 | +        self.assertRaises(TypeError, sys_audittuple, "test.event", ["list", "not", "tuple"]) | 
|  | 342 | +        self.assertRaises(TypeError, sys_audittuple, "test.event", {"dict": "not_tuple"}) | 
|  | 343 | +        self.assertRaises(TypeError, sys_audittuple, "test.event", None) | 
|  | 344 | + | 
| 214 | 345 | 
 | 
| 215 | 346 | if __name__ == "__main__": | 
| 216 | 347 |     unittest.main() | 
0 commit comments