"""
Description: python log test.
Author: ACC SDK
Create: 2025
History: NA
"""
import ctypes
import logging
import os
import sys
import tempfile
import types
from accsdk_pytest import BaseTestCase
from acc import LogCallBacker, Image, LogLevel_INFO, LogLevel_FATAL
logger = logging.getLogger("test_logger")
logger.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
logger.addHandler(ch)
call_count = 0
class LogCallBackerAux(LogCallBacker):
def __init__(self):
super().__init__()
def log(self, level, file, func, line, msg):
return
def custom_log(this, level, msg, file, line, func):
global call_count
call_count += 1
print("custom log:", level, file.decode("utf-8"),
func.decode("utf-8"), line, msg.decode("utf-8"))
logger.log(logging.ERROR, msg)
class TestPyLog(BaseTestCase):
def setUp(self):
self._cb = LogCallBackerAux()
self._orig_stdout_fd = os.dup(sys.stdout.fileno())
self._orig_stderr_fd = os.dup(sys.stderr.fileno())
self._tmpfile = tempfile.TemporaryFile(mode="w+")
os.dup2(self._tmpfile.fileno(), sys.stdout.fileno())
os.dup2(self._tmpfile.fileno(), sys.stderr.fileno())
def tearDown(self):
os.dup2(self._orig_stdout_fd, sys.stdout.fileno())
os.dup2(self._orig_stderr_fd, sys.stderr.fileno())
os.close(self._orig_stdout_fd)
os.close(self._orig_stderr_fd)
print("Captured C++ output:\n", self._captured_output)
def test_log_register_success_with_info_level(self):
global call_count
call_count = 0
self._cb.log = types.MethodType(custom_log, self._cb)
LogCallBacker.register_log_conf(LogLevel_INFO, self._cb)
with self.assertRaises(Exception):
image = Image.open(b"", b"cpu")
self.assertEqual(call_count, 5)
self._tmpfile.seek(0)
self._captured_output = self._tmpfile.read()
self._tmpfile.close()
self.assertIn('custom log:', self._captured_output)
def test_log_register_success_with_fatal_level(self):
global call_count
call_count = 0
self._cb = LogCallBackerAux()
self._cb.log = types.MethodType(custom_log, self._cb)
LogCallBacker.register_log_conf(LogLevel_FATAL, self._cb)
with self.assertRaises(Exception):
image = Image.open(b"", b"cpu")
self.assertEqual(call_count, 0)
self._tmpfile.seek(0)
self._captured_output = self._tmpfile.read()
self._tmpfile.close()
self.assertEqual(self._captured_output, "")
def test_log_default_with_info_level(self):
LogCallBacker.register_log_conf(LogLevel_INFO, None)
with self.assertRaises(Exception):
image = Image.open(b"", b"cpu")
libc = ctypes.CDLL(None)
libc.fflush(None)
self._tmpfile.seek(0)
self._captured_output = self._tmpfile.read()
self._tmpfile.close()
self.assertNotIn('custom log:', self._captured_output)
self.assertIn('Check file path failed. The path is empty.',
self._captured_output)
def test_log_default_with_fatal_level(self):
LogCallBacker.register_log_conf(LogLevel_FATAL, None)
with self.assertRaises(Exception):
image = Image.open(b"", b"cpu")
libc = ctypes.CDLL(None)
libc.fflush(None)
self._tmpfile.seek(0)
self._captured_output = self._tmpfile.read()
self._tmpfile.close()
self.assertNotIn('custom log:', self._captured_output)
self.assertNotIn(
'Check file path failed. The path is empty.', self._captured_output)
if __name__ == '__main__':
failed = TestPyLog.run_tests()
sys.exit(1 if failed > 0 else 0)