Exemple #1
0
def test_no_install(mock_command, tmp_path):
    "If an SDK is not available, and install is not requested, an error is raised"

    # Call `verify()`
    with pytest.raises(MissingToolError):
        AndroidSDK.verify(mock_command, jdk=MagicMock(), install=False)

    assert mock_command.download_url.call_count == 0
Exemple #2
0
def test_raises_networkfailure_on_connectionerror(mock_command):
    "If an error occurs downloading the ZIP file, and error is raised."
    mock_command.download_url.side_effect = requests_exceptions.ConnectionError()

    with pytest.raises(NetworkFailure):
        AndroidSDK.verify(mock_command, jdk=MagicMock())

    # The download was attempted
    mock_command.download_url.assert_called_once_with(
        url="https://dl.google.com/android/repository/sdk-tools-unknown-4333796.zip",
        download_path=mock_command.tools_path,
    )
    # But no unpack occurred
    assert mock_command.shutil.unpack_archive.call_count == 0
def mock_sdk(tmp_path):
    command = MagicMock()
    command.home_path = tmp_path
    command.host_platform = 'unknown'

    sdk = AndroidSDK(command, root_path=tmp_path)

    # Mock some existing emulators
    sdk.emulators = MagicMock(return_value=[
        'runningEmulator',
        'idleEmulator',
    ])

    return sdk
Exemple #4
0
 def verify_tools(self):
     """
     Verify that we the Android APK tools in `briefcase` will operate on
     this system, downloading tools as needed.
     """
     super().verify_tools()
     self.android_sdk = AndroidSDK.verify(self)
Exemple #5
0
def test_invalid_user_provided_sdk(mock_command, tmp_path):
    "If the user specifies an invalid ANDROID_SDK_ROOT, it is ignored"

    # Create `sdkmanager` and the license file
    # for the *briefcase* SDK.
    android_sdk_root_path = tmp_path / "tools" / "android_sdk"
    tools_bin = android_sdk_root_path / "tools" / "bin"
    tools_bin.mkdir(parents=True, mode=0o755)
    (tools_bin / "sdkmanager").touch(mode=0o755)

    # Pre-accept the license
    accept_license(android_sdk_root_path)()

    # Set the environment to specify an ANDROID_SDK_ROOT that doesn't exist
    mock_command.os.environ = {
        'ANDROID_SDK_ROOT': str(tmp_path / "other_sdk")
    }

    # Expect verify() to succeed
    sdk = AndroidSDK.verify(mock_command, jdk=MagicMock())

    # No calls to download, run or unpack anything.
    mock_command.download_url.assert_not_called()
    mock_command.subprocess.run.assert_not_called()
    mock_command.subprocess.check_output.assert_not_called()
    mock_command.shutil.unpack_archive.assert_not_called()

    # The returned SDK has the expected root path.
    assert sdk.root_path == android_sdk_root_path
Exemple #6
0
def test_user_provided_sdk(mock_command, tmp_path):
    "If the user specifies a valid ANDROID_SDK_ROOT, it is used"
    # Create `sdkmanager` and the license file.
    existing_android_sdk_root_path = tmp_path / "other_sdk"
    tools_bin = existing_android_sdk_root_path / "tools" / "bin"
    tools_bin.mkdir(parents=True, mode=0o755)
    (tools_bin / "sdkmanager").touch(mode=0o755)

    # Pre-accept the license
    accept_license(existing_android_sdk_root_path)()

    # Set the environment to specify ANDROID_SDK_ROOT
    mock_command.os.environ = {
        'ANDROID_SDK_ROOT': str(existing_android_sdk_root_path)
    }

    # Expect verify() to succeed
    sdk = AndroidSDK.verify(mock_command, jdk=MagicMock())

    # No calls to download, run or unpack anything.
    mock_command.download_url.assert_not_called()
    mock_command.subprocess.run.assert_not_called()
    mock_command.subprocess.check_output.assert_not_called()
    mock_command.shutil.unpack_archive.assert_not_called()

    # The returned SDK has the expected root path.
    # FIXME: The conversion to str is needed for Python 3.5 compatibility.
    assert str(sdk.root_path) == str(existing_android_sdk_root_path)
def mock_sdk(tmp_path):
    command = MagicMock()
    command.home_path = tmp_path

    # For default test purposes, assume we're on macOS x86_64
    command.host_os = "Darwin"
    command.host_arch = "x86_64"

    sdk = AndroidSDK(command, jdk=MagicMock(), root_path=tmp_path)

    # Mock some existing emulators
    sdk.emulators = MagicMock(return_value=[
        "runningEmulator",
        "idleEmulator",
    ])

    return sdk
def mock_sdk(tmp_path):
    command = MagicMock()
    command.logger = Log()
    command.input = DummyConsole()

    sdk = AndroidSDK(command, jdk=MagicMock(), root_path=tmp_path)

    sdk.devices = MagicMock(
        return_value={
            "041234567892009a": {
                "name": "Unknown device (not authorized for development)",
                "authorized": False,
            },
            "KABCDABCDA1513": {
                "name": "Kogan Agora 9",
                "authorized": True,
            },
            "emulator-5554": {
                "name": "Android SDK built for x86",
                "authorized": True,
            },
        })

    sdk.emulators = MagicMock(return_value=[
        "runningEmulator",
        "idleEmulator",
    ])

    # Set up an ADB for each device.
    def mock_adb(device_id):
        adb = MagicMock()
        if device_id == "emulator-5554":
            adb.avd_name.return_value = "runningEmulator"
        else:
            adb.avd_name.return_value = None
        return adb

    sdk.adb = mock_adb

    return sdk
Exemple #9
0
def mock_sdk(tmp_path):
    command = MagicMock()
    command.input = DummyConsole()

    sdk = AndroidSDK(command, root_path=tmp_path)

    sdk.devices = MagicMock(
        return_value={
            '041234567892009a': {
                'name': 'Unknown device (not authorized for development)',
                'authorized': False,
            },
            'KABCDABCDA1513': {
                'name': 'Kogan_Agora_9',
                'authorized': True,
            },
            'emulator-5554': {
                'name': 'generic_x86',
                'authorized': True,
            },
        })

    sdk.emulators = MagicMock(return_value=[
        'runningEmulator',
        'idleEmulator',
    ])

    # Set up an ADB for each device.
    def mock_adb(device_id):
        adb = MagicMock()
        if device_id == 'emulator-5554':
            adb.avd_name.return_value = 'runningEmulator'
        else:
            adb.avd_name.return_value = None
        return adb

    sdk.adb = mock_adb

    return sdk
Exemple #10
0
def mock_sdk(tmp_path):
    command = MagicMock()
    command.home_path = tmp_path
    command.subprocess = MagicMock()
    command.input = DummyConsole()

    # Mock an empty environment
    command.os.environ = {}

    # Set a JAVA_HOME
    command.java_home_path = Path('/path/to/jdk')

    sdk = AndroidSDK(command, root_path=tmp_path / 'sdk')

    return sdk
Exemple #11
0
def run_command(tmp_path, first_app_config):
    command = GradleRunCommand(base_path=tmp_path / "base_path")
    command.dot_briefcase_path = tmp_path / ".briefcase"
    command.java_home_path = tmp_path / "java"

    command.mock_adb = MagicMock()
    command.android_sdk = AndroidSDK(command, root_path=tmp_path)
    command.android_sdk.adb = MagicMock(return_value=command.mock_adb)

    command.os = MagicMock()
    command.os.environ = {}
    command.requests = MagicMock()
    command.subprocess = MagicMock()
    command.sys = MagicMock()
    return command
Exemple #12
0
def test_detects_bad_zipfile(mock_command, tmp_path):
    "If the ZIP file is corrupted, an error is raised."
    android_sdk_root_path = tmp_path / "tools" / "android_sdk"

    # The download will produce a cached file
    cache_file = MagicMock()
    cache_file.__str__.return_value = "/path/to/download.zip"
    mock_command.download_url.return_value = cache_file

    # But the unpack will fail.
    mock_command.shutil.unpack_archive.side_effect = shutil.ReadError

    with pytest.raises(BriefcaseCommandError):
        AndroidSDK.verify(mock_command, jdk=MagicMock())

    # The download attempt was made.
    mock_command.download_url.assert_called_once_with(
        url="https://dl.google.com/android/repository/sdk-tools-unknown-4333796.zip",
        download_path=mock_command.tools_path,
    )
    mock_command.shutil.unpack_archive.assert_called_once_with(
        "/path/to/download.zip",
        extract_dir=str(android_sdk_root_path)
    )
Exemple #13
0
def test_download_sdk(mock_command, tmp_path, host_os):
    "If an SDK is not available, one will be downloaded"
    android_sdk_root_path = tmp_path / "tools" / "android_sdk"

    # Mock-out `host_os` so we only do our permission check on non-Windows.
    mock_command.host_os = host_os

    # The download will produce a cached file
    cache_file = MagicMock()
    cache_file.__str__.return_value = "/path/to/download.zip"
    mock_command.download_url.return_value = cache_file

    # Create a file that would have been created by unpacking the archive
    example_tool = android_sdk_root_path / "tools" / "bin" / "exampletool"
    example_tool.parent.mkdir(parents=True)
    example_tool.touch(0o644)

    # Set up a side effect for accepting the license
    mock_command.subprocess.run.side_effect = accept_license(android_sdk_root_path)

    # Call `verify()`
    sdk = AndroidSDK.verify(mock_command, jdk=MagicMock())

    # Validate that the SDK was downloaded and unpacked
    url = "https://dl.google.com/android/repository/sdk-tools-{host_os}-4333796.zip".format(
        host_os=host_os.lower()
    )
    mock_command.download_url.assert_called_once_with(
        url=url,
        download_path=mock_command.tools_path,
    )
    mock_command.shutil.unpack_archive.assert_called_once_with(
        "/path/to/download.zip",
        extract_dir=str(android_sdk_root_path)
    )

    # The cached file will be deleeted
    cache_file.unlink.assert_called_once_with()

    # On non-Windows, ensure the unpacked binary was made executable
    if host_os != 'Windows':
        assert os.access(str(example_tool), os.X_OK)

    # The license has been accepted
    assert (android_sdk_root_path / "licenses" / "android-sdk-license").exists()

    # The returned SDK has the expected root path.
    assert sdk.root_path == android_sdk_root_path
Exemple #14
0
def mock_sdk(tmp_path):
    command = MagicMock()
    command.home_path = tmp_path
    command.subprocess = MagicMock()
    command.input = DummyConsole()
    command.logger = Log(verbosity=1)

    # For default test purposes, assume we're on macOS x86_64
    command.host_os = "Darwin"
    command.host_arch = "x86_64"

    # Mock an empty environment
    command.os.environ = {}

    # Set up a JDK
    jdk = MagicMock()
    jdk.java_home = Path("/path/to/jdk")

    sdk = AndroidSDK(command, jdk=jdk, root_path=tmp_path / "sdk")

    return sdk
Exemple #15
0
def test_download_sdk_if_sdkmanager_not_executable(mock_command, tmp_path):
    """An SDK will be downloaded and unpackged if `tools/bin/sdkmanager` exists
    but does not have its permissions set properly."""
    android_sdk_root_path = tmp_path / "tools" / "android_sdk"

    # Create non-executable `sdkmanager`.
    android_sdk_root_path = tmp_path / "tools" / "android_sdk"
    (android_sdk_root_path / "tools" / "bin").mkdir(parents=True)
    (android_sdk_root_path / "tools" / "bin" / "sdkmanager").touch(mode=0o644)

    # The download will produce a cached file
    cache_file = MagicMock()
    cache_file.__str__.return_value = "/path/to/download.zip"
    mock_command.download_url.return_value = cache_file

    # Set up a side effect for accepting the license
    mock_command.subprocess.run.side_effect = accept_license(android_sdk_root_path)

    # Call `verify()`
    sdk = AndroidSDK.verify(mock_command, jdk=MagicMock())

    # Validate that the SDK was downloaded and unpacked
    mock_command.download_url.assert_called_once_with(
        url="https://dl.google.com/android/repository/sdk-tools-unknown-4333796.zip",
        download_path=mock_command.tools_path,
    )
    mock_command.shutil.unpack_archive.assert_called_once_with(
        "/path/to/download.zip",
        extract_dir=str(android_sdk_root_path)
    )

    # The cached file will be deleted
    cache_file.unlink.assert_called_once_with()

    # The license has been accepted
    assert (android_sdk_root_path / "licenses" / "android-sdk-license").exists()

    # The returned SDK has the expected root path.
    assert sdk.root_path == android_sdk_root_path
Exemple #16
0
def test_succeeds_immediately_in_happy_path(mock_command, host_os, tmp_path):
    "If verify is invoked on a path containing an Android SDK, it does nothing."
    # If `sdkmanager` exists and has the right permissions, and
    # `android-sdk-license` exists, verify() should
    # succeed, create no subprocesses, make no requests, and return a
    # SDK wrapper.

    # On Windows, this requires `sdkmanager.bat`; on non-Windows, it requires
    # `sdkmanager`.

    # Create `sdkmanager` and the license file.
    android_sdk_root_path = tmp_path / "tools" / "android_sdk"
    tools_bin = android_sdk_root_path / "tools" / "bin"
    tools_bin.mkdir(parents=True, mode=0o755)
    if host_os == "Windows":
        (tools_bin / "sdkmanager.bat").touch()
    else:
        (tools_bin / "sdkmanager").touch(mode=0o755)

    # Pre-accept the license
    accept_license(android_sdk_root_path)()

    # Configure `mock_command` to assume the `host_os` we parameterized with.
    mock_command.host_os = host_os

    # Expect verify() to succeed
    sdk = AndroidSDK.verify(mock_command, jdk=MagicMock())

    # No calls to download, run or unpack anything.
    mock_command.download_url.assert_not_called()
    mock_command.subprocess.run.assert_not_called()
    mock_command.subprocess.check_output.assert_not_called()
    mock_command.shutil.unpack_archive.assert_not_called()

    # The returned SDK has the expected root path.
    assert sdk.root_path == android_sdk_root_path
def mock_sdk(tmp_path):
    command = MagicMock()
    command.host_platform = 'unknown'

    sdk = AndroidSDK(command, root_path=tmp_path)
    sdk.sleep = MagicMock()

    sdk.mock_run = MagicMock()

    def mock_adb(device):
        adb = ADB(sdk, device)
        adb.run = sdk.mock_run
        return adb
    sdk.adb = mock_adb

    # Mock some existing emulators
    sdk.emulators = MagicMock(return_value=[
        'runningEmulator',
        'idleEmulator',
    ])

    return sdk