Files
uiautomator2/tests/test_core.py
Copilot b407b9eb88 Fix MD5 hash check fallback for devices without toybox (#1146)
* Initial plan

* Add MD5 hash check fallback from toybox to md5 command

Co-authored-by: codeskyblue <3281689+codeskyblue@users.noreply.github.com>

* Improve MD5 check specificity and refactor tests with fixture

Co-authored-by: codeskyblue <3281689+codeskyblue@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: codeskyblue <3281689+codeskyblue@users.noreply.github.com>
2025-11-11 19:09:30 +08:00

110 lines
4.4 KiB
Python

# coding: utf-8
#
import hashlib
from unittest.mock import Mock, mock_open, patch
import pytest
from uiautomator2.core import BasicUiautomatorServer
@pytest.fixture
def mock_server():
"""Create a mock BasicUiautomatorServer instance with a mock device"""
mock_dev = Mock()
with patch.object(BasicUiautomatorServer, '__init__', return_value=None):
server = BasicUiautomatorServer(None)
server._dev = mock_dev
yield server, mock_dev
class TestCheckDeviceFileHash:
"""Test the _check_device_file_hash method with toybox fallback"""
def test_toybox_md5sum_success(self, mock_server):
"""Test when toybox md5sum command works correctly"""
server, mock_dev = mock_server
# Create a temporary file with known content
test_content = b"test content for md5"
local_md5 = hashlib.md5(test_content).hexdigest()
# Mock the shell command to return toybox md5sum output
# Format: "md5hash filename"
mock_dev.shell.return_value = f"{local_md5} /data/local/tmp/u2.jar"
# Mock the file read to return our test content
with patch("builtins.open", mock_open(read_data=test_content)):
result = server._check_device_file_hash("test.jar", "/data/local/tmp/u2.jar")
# Verify the result is True (hash matches)
assert result is True
# Verify toybox md5sum was called
mock_dev.shell.assert_called_once_with(["toybox", "md5sum", "/data/local/tmp/u2.jar"])
def test_toybox_not_found_fallback_to_md5(self, mock_server):
"""Test fallback to md5 command when toybox is not found"""
server, mock_dev = mock_server
# Create a temporary file with known content
test_content = b"test content for md5"
local_md5 = hashlib.md5(test_content).hexdigest()
# Mock the shell command to return different outputs
# First call: toybox not found
# Second call: md5 command output (format: "MD5 (filename) = md5hash")
mock_dev.shell.side_effect = [
"toybox: not found",
f"MD5 (/data/local/tmp/u2.jar) = {local_md5}"
]
# Mock the file read to return our test content
with patch("builtins.open", mock_open(read_data=test_content)):
result = server._check_device_file_hash("test.jar", "/data/local/tmp/u2.jar")
# Verify the result is True (hash matches)
assert result is True
# Verify both commands were called
assert mock_dev.shell.call_count == 2
assert mock_dev.shell.call_args_list[0][0][0] == ["toybox", "md5sum", "/data/local/tmp/u2.jar"]
assert mock_dev.shell.call_args_list[1][0][0] == ["md5", "/data/local/tmp/u2.jar"]
def test_hash_mismatch(self, mock_server):
"""Test when the hash doesn't match"""
server, mock_dev = mock_server
# Create a temporary file with known content
test_content = b"test content for md5"
different_md5 = hashlib.md5(b"different content").hexdigest()
# Mock the shell command to return a different hash
mock_dev.shell.return_value = f"{different_md5} /data/local/tmp/u2.jar"
# Mock the file read to return our test content
with patch("builtins.open", mock_open(read_data=test_content)):
result = server._check_device_file_hash("test.jar", "/data/local/tmp/u2.jar")
# Verify the result is False (hash doesn't match)
assert result is False
def test_md5_command_also_fails(self, mock_server):
"""Test when both toybox and md5 commands fail to find the file"""
server, mock_dev = mock_server
# Create a temporary file with known content
test_content = b"test content for md5"
# Mock the shell command to return errors for both commands
mock_dev.shell.side_effect = [
"toybox: not found",
"md5: /data/local/tmp/u2.jar: No such file or directory"
]
# Mock the file read to return our test content
with patch("builtins.open", mock_open(read_data=test_content)):
result = server._check_device_file_hash("test.jar", "/data/local/tmp/u2.jar")
# Verify the result is False (file not found on device)
assert result is False