tests/TestInit.py
Rama master · réplica de lectura del repositorio original.
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright (c) 2008-2026 Andrew Ziem.
#
# This work is licensed under the terms of the GNU GPL, version 3 or
# later. See the COPYING file in the top-level directory.
"""
Test cases for __init__
"""
# These tests reach into internals on purpose.
# pylint: disable=protected-access
import os
import re
import shutil
import subprocess
import sys
import tempfile
import unittest
from unittest import mock
import bleachbit
from bleachbit import IS_MAC, IS_POSIX, IS_WINDOWS, get_share_dirs, get_share_path
from bleachbit.General import get_executable
from tests import common
class InitTestCase(common.BleachbitTestCase):
"""Test cases for __init__"""
def test_expanduser(self):
"""Unit test for function expanduser()"""
# already absolute
test_input = '/home/user/foo'
test_output = os.path.expanduser(test_input)
self.assertEqual(test_input, test_output)
# tilde not at beginning
test_input = '/home/user/~'
test_output = os.path.expanduser(test_input)
self.assertEqual(test_input, test_output)
# should be expanded
test_inputs = ()
if IS_WINDOWS:
test_inputs = ('~', r'~\ntuser.dat')
elif IS_MAC:
# macOS defaults to zsh
test_inputs = ('~', '~/.zshrc')
elif IS_POSIX:
test_inputs = ('~', '~/.profile')
for test_input in test_inputs:
test_output = os.path.expanduser(test_input)
self.assertNotEqual(test_input, test_output)
msg = None
if not os.path.exists(test_output) and not test_input == '~':
msg = f"contents of home directory: {os.listdir(os.path.expanduser('~'))}"
self.assertExists(test_output, msg)
if IS_POSIX:
self.assertTrue(os.path.samefile(
test_output, os.path.expanduser(test_input)))
def test_seconds_since_process_start(self):
"""Process age is known on Windows and Linux and is a small number"""
seconds = bleachbit._seconds_since_process_start()
if IS_WINDOWS or sys.platform.startswith('linux'):
self.assertIsNotNone(seconds)
if seconds is not None:
self.assertGreaterEqual(seconds, 0)
self.assertLess(seconds, 24 * 3600)
def test_log_startup_time(self):
"""The first milestone logs the package import and arms the exit one"""
clock = bleachbit._startup_clock
saved = (clock.t0, clock.enabled, clock.rebased)
clock.enabled = True
clock.rebased = False
try:
with mock.patch('bleachbit.atexit.register') as register, \
self.assertLogs('bleachbit', level='INFO') as cm:
bleachbit.log_startup_time('test milestone')
finally:
clock.t0, clock.enabled, clock.rebased = saved
register.assert_called_once_with(clock._log, 'atexit done')
times = [re.fullmatch(r'INFO:bleachbit:startup (.+): ([0-9.]+) ms', line)
for line in cm.output]
self.assertEqual([m.group(1) for m in times],
['package imported', 'test milestone'])
self.assertLessEqual(
float(times[0].group(2)), float(times[1].group(2)))
def test_get_share_dirs(self):
"""Unit test for get_share_dirs()"""
got_shared_dirs = get_share_dirs()
# There must be at least one shared directory.
self.assertGreater(len(got_shared_dirs), 0)
existing = [d for d in got_shared_dirs if os.path.isdir(d)]
# At least one of the shared directories must exist.
self.assertGreater(len(existing), 0,
f'No share dir exists among: {got_shared_dirs}')
def test_get_share_path(self):
"""Unit test for get_share_path()"""
for fn in ('app-menu.ui', 'protected_path.xml'):
self.assertExists(get_share_path(fn))
self.assertIsNone(get_share_path('nonexistent'))
def test_icon_lookup_covers_make_install(self):
"""The icon path of a default make install is looked up"""
makefile = os.path.join(os.path.dirname(os.path.dirname(
os.path.abspath(__file__))), 'Makefile')
with open(makefile, encoding='utf-8') as f:
text = f.read()
prefix = re.search(r'^prefix \?= (\S+)$', text, re.M).group(1)
self.assertRegex(text, r'(?m)^datadir \?= \$\(prefix\)/share$')
self.assertIn('bleachbit.png $(DESTDIR)$(datadir)/pixmaps/', text)
self.assertIn(prefix + '/share/pixmaps/bleachbit.png',
getattr(bleachbit, '__icons'))
def test_stdout_encoding_frozen_console(self):
"""A frozen console build uses the encoding of a redirected stdout"""
script = '''
import io
import sys
sys.frozen = 'console_exe'
sys.stdout = io.TextIOWrapper(io.BytesIO(), encoding='cp1252')
import bleachbit
sys.stderr.write('encoding=' + bleachbit.stdout_encoding)
'''
result = subprocess.run(
[get_executable(), '-c', script],
capture_output=True, text=True, timeout=30, check=False)
self.assertEqual(result.returncode, 0, f'stderr: {result.stderr}')
self.assertIn('encoding=cp1252', result.stderr)
@common.skipUnlessWindows
def test_harden_dll_search_path(self):
"""The current directory is not on the DLL search path"""
import ctypes
from ctypes import wintypes
ERROR_MOD_NOT_FOUND = 126
src = os.path.join(os.environ['SystemRoot'], 'System32', 'version.dll')
tmpdir = tempfile.mkdtemp()
planted = os.path.join(tmpdir, 'bb_dll_preload_test.dll')
shutil.copy(src, planted)
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
load = kernel32.LoadLibraryW
load.argtypes = [wintypes.LPCWSTR]
load.restype = wintypes.HMODULE
free = kernel32.FreeLibrary
free.argtypes = [wintypes.HMODULE]
orig_cwd = os.getcwd()
try:
os.chdir(tmpdir)
bleachbit._harden_dll_search_path()
# By bare name the DLL must not be found in the current directory
ctypes.set_last_error(0)
handle = load('bb_dll_preload_test.dll')
if handle:
free(handle)
self.assertFalse(
handle, 'current directory still on DLL search path')
self.assertEqual(ctypes.get_last_error(), ERROR_MOD_NOT_FOUND)
# A full path still loads
handle = load(planted)
self.assertTrue(handle)
free(handle)
finally:
os.chdir(orig_cwd)
shutil.rmtree(tmpdir, ignore_errors=True)
def suite():
"""Return a test suite"""
return unittest.TestLoader().loadTestsFromTestCase(InitTestCase)