blob: 835ddd17bd9dc0fd1984e3cb68ae10b5b87a72e5 [file] [log] [blame]
"""Test deps.
Testing adds more requirements, as we use Pytest. That is not needed for running though.
"""
import json
import os
import sys
import pytest
import subprocess
import dep
from dep import Line, Version, MissingDependencyError
here = os.path.dirname(os.path.realpath(__file__))
def test_simple_brew():
"""End-to-end test of a simple brew dependency."""
dep.parse_dependencies(['./tests/Dependencies0'])
def test_main():
"""End-to-end test of larger dependency file."""
sys.argv = ['/bin/deps', 'verify', './tests/Dependencies1']
with pytest.raises(dep.MalformedDependency):
dep.main()
def test_brew_cmake_requirement(mocker):
"""Detailed check of a brew cmake dependency."""
line = Line("foo.c", 10, "brew cmake <= 3.10.0", "test")
b = dep.Brew(line, "brew")
b.parse()
assert b.operator == "<="
assert b.command == "brew"
assert b.package == "cmake"
assert b.version_text == "3.10.0"
mocker.patch('dep.brew_cmd')
dep.brew_cmd.return_value = json.load(open(here + '/assets/brew_cmake_installed.json'))
b.verify_and_act()
assert dep.brew_cmd.called
mocker.patch('dep.brew_cmd')
dep.brew_cmd.side_effect = OSError()
with pytest.raises(MissingDependencyError):
b.verify_and_act()
def test_brew_ninja_not_installed_requirement(mocker):
"""Detailed check of a unmatched brew requirement."""
line = Line("foo.c", 11, "brew ninja <= 1.8.2", "We use ninja as clang's build system.")
b = dep.Brew(line, "brew")
b.parse()
assert b.operator == "<="
assert b.command == "brew"
assert b.package == "ninja"
assert b.version_text == "1.8.2"
mocker.patch('dep.brew_cmd')
dep.brew_cmd.return_value = json.load(open(here + '/assets/brew_ninja_not_installed.json'))
# The package is not installed
with pytest.raises(MissingDependencyError) as exception_info:
b.verify_and_act()
assert "missing dependency: brew ninja v1.8.2, found nothing installed" in str(exception_info)
assert dep.brew_cmd.called
def test_versions():
"""Unittests for the version comparison objects."""
v1 = Version("3.2.1")
v2 = Version("3.3.1")
v3 = Version("3.2")
v4 = Version("3.2")
# Check the values are parsed correctly.
assert v1.text == "3.2.1"
assert v1.numeric == [3, 2, 1]
assert v3.text == "3.2"
assert v3.numeric == [3, 2]
# Check the operators work correctly.
assert v2 > v1
assert v1 < v2
assert v2 >= v1
assert v1 <= v2
assert v3 == v4
# Check that versions with different number of digits compare correctly.
assert v2 > v3
assert v3 < v2
# TODO fix different digit comparisons.
# assert v4 == v1
assert v3 >= v4
def test_self_version_requirement():
"""Unittest of the self version check."""
line = Line("foo.c", 10, "config_manager <= 0.1", "test")
b = dep.ConMan(line, "config_manager")
b.parse()
assert b.operator == "<="
assert b.command == "config_manager"
assert b.version_text == "0.1"
b.verify_and_act()
line = Line("foo.c", 10, "config_manager <= 0.0.1", "test")
bad = dep.ConMan(line, "config_manager")
bad.parse()
with pytest.raises(MissingDependencyError):
bad.verify_and_act()
line = Line("foo.c", 10, "config_manager == " + dep.VERSION, "test")
good = dep.ConMan(line, "config_manager")
good.parse()
good.verify_and_act()
def test_host_os_version_requirement(mocker):
"""Unittest of the host os version check."""
line = Line("foo.c", 11, "os_version == 10.13.2", "test")
mocker.patch('dep.platform.mac_ver')
dep.platform.mac_ver.return_value = ('10.13.2', "", "")
b = dep.HostOSVersion(line, "os_version")
b.parse()
assert b.operator == "=="
assert b.command == "os_version"
assert b.version_text == "10.13.2"
b.verify_and_act()
line = Line("foo.c", 10, "os_version == 10.13.1", "test")
bad = dep.HostOSVersion(line, "os_version")
bad.parse()
with pytest.raises(MissingDependencyError):
bad.verify_and_act()
XCODE_VERSION_OUTPUT = """Xcode 1.0
Build version 1A123b
"""
def test_xcode_version_requirement(mocker):
"""Unittest of the Xcode version check."""
line = Line("foo.c", 11, "xcode == 1.0", "test")
mocker.patch('dep.subprocess.check_output')
dep.subprocess.check_output.return_value = XCODE_VERSION_OUTPUT
b = dep.Xcode(line, "xcode")
b.parse()
assert b.operator == "=="
assert b.command == "xcode"
assert b.version_text == "1.0"
b.verify_and_act()
line = Line("foo.c", 10, "xcode == 2.0", "test")
bad = dep.Xcode(line, "xcode")
bad.parse()
with pytest.raises(MissingDependencyError):
bad.verify_and_act()
SDK_VERSION_OUTPUT = """iOS SDKs:
iOS 1.0 -sdk iphoneos1.0
iOS Simulator SDKs:
Simulator - iOS 1.0 -sdk iphonesimulator1.0
macOS SDKs:
macOS 10.11 -sdk macosx10.11
macOS 10.12 -sdk macosx10.12
macOS Additional SDKs:
iDishwasher SDK -sdk iwash
""" # noqa This is literal output, it is okay to mix tabs.
def test_sdk_version_requirement(mocker):
"""Unittest of the SDK version check."""
line = Line("foo.c", 11, "sdk iphoneos == 1.0", "test")
mocker.patch('dep.subprocess.check_output')
dep.subprocess.check_output.return_value = SDK_VERSION_OUTPUT
b = dep.Sdk(line, "sdk")
b.parse()
assert b.operator == "=="
assert b.command == "sdk"
assert b.sdk == "iphoneos"
assert b.version_text == "1.0"
b.verify_and_act()
line = Line("foo.c", 10, "sdk iphoneos == 2.0", "test")
bad = dep.Sdk(line, "sdk")
bad.parse()
with pytest.raises(MissingDependencyError):
bad.verify_and_act()
b = dep.Sdk(Line("foo.c", 11, "sdk iphoneos == 1.0", "test"), "sdk")
b.parse()
b.verify_and_act()
b = dep.Sdk(Line("foo.c", 11, "sdk iphoneos <= 1.0", "test"), "sdk")
b.parse()
b.verify_and_act()
b = dep.Sdk(Line("foo.c", 11, "sdk iphonesimulator <= 1.0", "test"), "sdk")
b.parse()
b.verify_and_act()
b = dep.Sdk(Line("foo.c", 11, "sdk iwash == 1.0", "test"), "sdk")
b.parse()
# TODO handle unversioned SDKs.
with pytest.raises(MissingDependencyError):
b.verify_and_act()
b = dep.Sdk(Line("foo.c", 11, "sdk macosx == 10.12", "test"), "sdk")
b.parse()
b.verify_and_act()
b = dep.Sdk(Line("foo.c", 11, "sdk macosx == 10.11", "test"), "sdk")
b.parse()
b.verify_and_act()
def test_pip_requirement(mocker):
"""Detailed check of a pip packages dependency."""
line = Line("foo.c", 10, "pip pytest <= 3.3.1", "test")
b = dep.Pip(line, "pip")
b.parse()
assert b.operator == "<="
assert b.command == "pip"
assert b.package == "pytest"
assert b.version_text == "3.3.1"
# Check an old version of pip raises a dependency error.
mocker.patch('dep.subprocess.check_output')
dep.subprocess.check_output.side_effect = ["pip 1.2.3 from /Python/pip-1.3.1-py2.7.egg (python 2.7)",
open(here + '/assets/pip_output.json').read()]
with pytest.raises(MissingDependencyError):
b.verify_and_act()
num_of_checks = 4
mocker.patch('dep.subprocess.check_output')
dep.subprocess.check_output.side_effect = ["pip 9.0.1 from /Python/pip-1.3.1-py2.7.egg (python 2.7)",
open(here + '/assets/pip_output.json').read()] * num_of_checks
b.verify_and_act()
assert dep.subprocess.check_output.called
b = dep.Pip(Line("foo.c", 10, "pip pytest == 3.3.1", "test"), "pip")
b.parse()
b.verify_and_act()
b = dep.Pip(Line("foo.c", 10, "pip pytest <= 3.3.0", "test"), "pip")
b.parse()
with pytest.raises(MissingDependencyError):
b.verify_and_act()
mocker.patch('dep.subprocess.check_output')
no_pip = "/usr/bin/python: No module named pip"
dep.subprocess.check_output.side_effect = subprocess.CalledProcessError(1, [], output=no_pip)
with pytest.raises(MissingDependencyError):
b.verify_and_act()
def test_device_requirement(mocker):
"""Detailed check of a device udid dependency."""
line = Line("foo.c", 10, "device aaabbbeeeec5fffff38bc8511112c2225f7333d44", "test")
b = dep.Device(line, "device")
b.parse()
with pytest.raises(MissingDependencyError):
b.verify_and_act()
mocker.patch('dep.subprocess.check_output')
dep.subprocess.check_output.side_effect = [open(here + '/assets/instruments_output.txt').read()]
b.verify_and_act()