aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAri Hausman-Cohen <arihc@google.com>2016-05-09 16:00:27 -0700
committerAri Hausman-Cohen <arihc@google.com>2016-05-09 17:20:26 -0700
commitae13a180487a8f9314e76ec827f2dfe8ce09e2bd (patch)
treea40f9871992ab78fdc0a4419b3a6ee398a06f3a2
parent8d656f43fd2d2ff5f76edb41a21c52e70424e2fa (diff)
downloadbdk-ae13a180487a8f9314e76ec827f2dfe8ce09e2bd.tar.gz
Moved platform link context manager into platform.
BUG: 28527859 Change-Id: I7ecde3882f601e33243ad30e1ec5872d662efced TEST: unit tests pass, ran modified commands
-rw-r--r--cli/lib/bsp/device.py75
-rw-r--r--cli/lib/bsp/device_stub.py17
-rw-r--r--cli/lib/bsp/device_unittest.py99
-rw-r--r--cli/lib/bsp/operating_system.py3
-rw-r--r--cli/lib/commands/bsp/download.py5
-rw-r--r--cli/lib/commands/product/build.py16
-rw-r--r--cli/lib/commands/product/provision.py14
-rw-r--r--cli/lib/core/build_unittest.py5
-rw-r--r--cli/lib/core/image_build_unittest.py9
-rw-r--r--cli/lib/core/provision_unittest.py5
-rw-r--r--cli/lib/core/tool_unittest.py4
-rw-r--r--cli/lib/environment/toolchain_util_unittest.py3
-rw-r--r--cli/lib/project/platform.py47
-rw-r--r--cli/lib/project/platform_stub.py24
-rw-r--r--cli/lib/project/platform_unittest.py11
15 files changed, 147 insertions, 190 deletions
diff --git a/cli/lib/bsp/device.py b/cli/lib/bsp/device.py
index 6378051..8570659 100644
--- a/cli/lib/bsp/device.py
+++ b/cli/lib/bsp/device.py
@@ -57,37 +57,6 @@ class PackageUnlinkError(Error):
description = 'Failed to unlink BSP from OS tree'
-class _LinkContext(object):
- """A context manager to allow temporary linking of a device to an OS.
-
- Attributes:
- device: The device to temporarily link.
- os_version: The os version to temporarily link to.
- """
-
- def __init__(self, device, os_version):
- self.device = device
- self.os_version = os_version
-
- def __enter__(self):
- success = False
- try:
- self.device.link(self.os_version)
- success = True
- finally:
- # If something goes wrong, leave unlinked.
- if not success:
- self.cleanup()
-
- def __exit__(self, type_, value_, traceback_):
- # TODO(b/28028440): Even if you were linked initially, when
- # exiting the context the links will be removed.
- self.cleanup()
-
- def cleanup(self):
- self.device.unlink(self.os_version)
-
-
class Device(object):
"""Class to represent devices with BSPs available.
@@ -166,13 +135,13 @@ class Device(object):
"""
return self.status()[0] == status.INSTALLED
- def link(self, os_version):
+ def link(self, os_):
"""Links an OS to this device.
Does not overwrite anything; ignores situations where it would need to.
Args:
- os_version: The OS to link to this device.
+ os_: The OS to link to this device.
Raises:
PackageLinkError: if a package problem occurs while linking.
@@ -181,7 +150,7 @@ class Device(object):
errors = []
for (pkg, subpackage_map) in self._package_map.iteritems():
for (subpackage_name, relpath) in subpackage_map.iteritems():
- link = util.GetOSPath(os_version, relpath)
+ link = os_.path(relpath)
# Don't overwrite anything.
if os.path.exists(link):
continue
@@ -196,16 +165,16 @@ class Device(object):
break
if errors:
- raise PackageLinkError('OS version {}: {}'.format(os_version,
- errors))
+ raise PackageLinkError('{} to {}: {}'.format(self.name,
+ os_, errors))
- def unlink(self, os_version):
+ def unlink(self, os_):
"""Unlinks this device from an OS.
Removes links of LINKED subpackages.
Args:
- os_version: The OS to unlink from.
+ os_: The OS to unlink from.
Raises:
PackageUnlinkError: if a package problem occurs while unlinking.
@@ -214,7 +183,7 @@ class Device(object):
errors = []
for (pkg, subpackage_map) in self._package_map.iteritems():
for (subpackage, relpath) in subpackage_map.iteritems():
- link = util.GetOSPath(os_version, relpath)
+ link = os_.path(relpath)
try:
subpackage_status, _ = pkg.subpackage_status(
subpackage, link)
@@ -223,22 +192,8 @@ class Device(object):
except package.Error as e:
errors.append('{}: {}'.format(pkg, e))
if errors:
- raise PackageUnlinkError('OS version {}: {}'.format(os_version,
- errors))
-
- def linked(self, os_version):
- """A context manager for temporary linkage.
-
- Note: b/28028440: It is a known bug that after exiting the context,
- the device will be unlinked, whether or not it was linked going in.
-
- Args:
- os_version: The OS version to temporarily link against.
-
- Returns:
- A context manager within which the BSP and OS will be linked.
- """
- return _LinkContext(self, os_version)
+ raise PackageUnlinkError('{} from {}: {}'.format(self.name, os_,
+ errors))
def unrecognized_paths(self, os_version):
"""Get the paths of unrecognized subpackages of this device.
@@ -351,7 +306,7 @@ class Device(object):
return confirmed
- def install(self, extract_only=None, auto_accept=False, link_os_version='',
+ def install(self, extract_only=None, auto_accept=False, link_os=None,
verbose=False):
"""Installs the BSP for this device.
@@ -359,7 +314,7 @@ class Device(object):
extract_only: (optional) a map of { package_name : tarball_file },
for packages to skip the tarball download step.
auto_accept: (optional) True to accept all licenses automatically.
- link_os_version: (optional) An OS version to link packages into.
+ link_os: (optional) An OS to link packages into.
Intended only for when developing the OS/BSP, not for use with
product development flow.
verbose: (optional) If True, print status messages. Default False.
@@ -370,7 +325,7 @@ class Device(object):
Raises:
LicenseError: if the user does not accept all licenses.
PackageLinkError: if a package fails to link to the tree.
- (Will not occur if link_os_version is None or empty)
+ (Will not occur if link_os is None)
PackageDownloadError: if a required bsp.Package fails to download.
package.NoSuchSubpackageError: if the package map is not correctly
validated and specifies a non-existant subpackage.
@@ -405,8 +360,8 @@ class Device(object):
pkg.uninstall()
# If requested, go ahead and install the links.
- if link_os_version:
- self.link(link_os_version)
+ if link_os:
+ self.link(link_os)
def uninstall(self):
"""Uninstalls all BSP packages for a device.
diff --git a/cli/lib/bsp/device_stub.py b/cli/lib/bsp/device_stub.py
index 2a47ae9..6200782 100644
--- a/cli/lib/bsp/device_stub.py
+++ b/cli/lib/bsp/device_stub.py
@@ -19,7 +19,6 @@
from bsp import device
-from test import stubs
class Error(device.Error):
@@ -30,21 +29,21 @@ class StubDevice(object):
def __init__(self, name='', full_name='', vendor='', arch='',
package_map=None, version='', downloaded=False,
- should_link_version=None):
+ is_linked=False):
self.name = name
self.full_name = full_name
self.vendor = vendor
self.arch = arch
self.version = version
self.package_map = package_map or {}
- self.should_link_version = should_link_version
+ self.is_linked = is_linked
self.downloaded = downloaded
- def linked(self, os_version):
- if not self.should_link_version == os_version:
- raise Error('Not supposed to link to {} (only to {})'.format(
- os_version, self.should_link_version))
- return stubs.StubContextManager()
-
def is_available(self):
return self.downloaded
+
+ def link(self, _os):
+ self.is_linked = True
+
+ def unlink(self, _os):
+ self.is_linked = False
diff --git a/cli/lib/bsp/device_unittest.py b/cli/lib/bsp/device_unittest.py
index 53ca216..a1afab3 100644
--- a/cli/lib/bsp/device_unittest.py
+++ b/cli/lib/bsp/device_unittest.py
@@ -20,6 +20,7 @@
import unittest
from bsp import device
+from bsp import operating_system_stub
from bsp import package
from bsp import package_stub
from bsp import status
@@ -29,7 +30,8 @@ from test import stubs
class DeviceTest(unittest.TestCase):
- _OS_VERSION = '98.76'
+ _OS_VERSION = '98.76.54'
+ _OS_PATH = '/path/to/os'
def setUp(self):
self.dev_json = {
@@ -67,6 +69,7 @@ class DeviceTest(unittest.TestCase):
'test_device', 'Test Device', 'test_vendor', 'test_arch',
{self.package1: {'subpackage_1': 'path1', 'subpackage_2': 'path2'},
self.package2: {'subpackage_2': 'path3'}})
+ self.os_ = operating_system_stub.StubOperatingSystem(root=self._OS_PATH)
def test_init(self):
# Check all public attributes.
@@ -166,14 +169,14 @@ class DeviceTest(unittest.TestCase):
self.assertFalse(self.dev.is_available())
def test_link(self):
- link1 = self.stub_util.GetOSPath(self._OS_VERSION, 'path1')
- link2 = self.stub_util.GetOSPath(self._OS_VERSION, 'path2')
- link3 = self.stub_util.GetOSPath(self._OS_VERSION, 'path3')
+ link1 = self.os_.path('path1')
+ link2 = self.os_.path('path2')
+ link3 = self.os_.path('path3')
self.package1.should_link['subpackage_1'] = link1
self.package1.should_link['subpackage_2'] = link2
self.package2.should_link['subpackage_2'] = link3
- self.dev.link(self._OS_VERSION)
+ self.dev.link(self.os_)
self.assertEqual(self.package1.subpackage_status(
'subpackage_1', link1)[0], status.LINKED)
self.assertEqual(self.package1.subpackage_status(
@@ -182,15 +185,15 @@ class DeviceTest(unittest.TestCase):
'subpackage_2', link3)[0], status.LINKED)
def test_link_fail(self):
- link1 = self.stub_util.GetOSPath(self._OS_VERSION, 'path1')
- link2 = self.stub_util.GetOSPath(self._OS_VERSION, 'path2')
- link3 = self.stub_util.GetOSPath(self._OS_VERSION, 'path3')
+ link1 = self.os_.path('path1')
+ link2 = self.os_.path('path2')
+ link3 = self.os_.path('path3')
self.package1.should_link['subpackage_1'] = link1
# Gonna be problems with package1.subpackage_2
self.package2.should_link['subpackage_2'] = link3
with self.assertRaises(device.PackageLinkError):
- self.dev.link(self._OS_VERSION)
+ self.dev.link(self.os_)
# Should still link what it can.
self.assertEqual(self.package1.subpackage_status(
'subpackage_1', link1)[0], status.LINKED)
@@ -200,16 +203,16 @@ class DeviceTest(unittest.TestCase):
'subpackage_2', link3)[0], status.LINKED)
def test_link_not_downloaded(self):
- link1 = self.stub_util.GetOSPath(self._OS_VERSION, 'path1')
- link2 = self.stub_util.GetOSPath(self._OS_VERSION, 'path2')
- link3 = self.stub_util.GetOSPath(self._OS_VERSION, 'path3')
+ link1 = self.os_.path('path1')
+ link2 = self.os_.path('path2')
+ link3 = self.os_.path('path3')
self.package1.should_link['subpackage_1'] = link1
self.package1.should_link['subpackage_2'] = link2
self.package2.should_link['subpackage_2'] = link3
self.package2.downloaded = False
with self.assertRaises(device.PackageLinkError):
- self.dev.link(self._OS_VERSION)
+ self.dev.link(self.os_)
# Should still link what it can.
self.assertEqual(self.package1.subpackage_status(
'subpackage_1', link1)[0], status.LINKED)
@@ -219,15 +222,15 @@ class DeviceTest(unittest.TestCase):
'subpackage_2', link3)[0], status.LINKED)
def test_link_overwrite(self):
- link1 = self.stub_util.GetOSPath(self._OS_VERSION, 'path1')
- link2 = self.stub_util.GetOSPath(self._OS_VERSION, 'path2')
- link3 = self.stub_util.GetOSPath(self._OS_VERSION, 'path3')
+ link1 = self.os_.path('path1')
+ link2 = self.os_.path('path2')
+ link3 = self.os_.path('path3')
self.package1.should_link['subpackage_1'] = link1
self.stub_os.path.should_exist = [link2]
self.package2.should_link['subpackage_2'] = link3
# Shouldn't raise, but shouldn't link package1.subpackage_2.
- self.dev.link(self._OS_VERSION)
+ self.dev.link(self.os_)
self.assertEqual(self.package1.subpackage_status(
'subpackage_1', link1)[0], status.LINKED)
self.assertNotEqual(self.package1.subpackage_status(
@@ -236,9 +239,9 @@ class DeviceTest(unittest.TestCase):
'subpackage_2', link3)[0], status.LINKED)
def test_unlink(self):
- link1 = self.stub_util.GetOSPath(self._OS_VERSION, 'path1')
- link2 = self.stub_util.GetOSPath(self._OS_VERSION, 'path2')
- link3 = self.stub_util.GetOSPath(self._OS_VERSION, 'path3')
+ link1 = self.os_.path('path1')
+ link2 = self.os_.path('path2')
+ link3 = self.os_.path('path3')
self.package1.subpackages['subpackage_1'] = status.LINKED
self.package1.subpackages['subpackage_2'] = status.LINKED
self.package2.subpackages['subpackage_2'] = status.LINKED
@@ -246,7 +249,7 @@ class DeviceTest(unittest.TestCase):
self.package1.should_unlink['subpackage_2'] = link2
self.package2.should_unlink['subpackage_2'] = link3
- self.dev.unlink(self._OS_VERSION)
+ self.dev.unlink(self.os_)
self.assertEqual(self.package1.subpackage_status(
'subpackage_1', link1)[0], status.INSTALLED)
self.assertEqual(self.package1.subpackage_status(
@@ -255,9 +258,9 @@ class DeviceTest(unittest.TestCase):
'subpackage_2', link3)[0], status.INSTALLED)
def test_partial_unlink(self):
- link1 = self.stub_util.GetOSPath(self._OS_VERSION, 'path1')
- link2 = self.stub_util.GetOSPath(self._OS_VERSION, 'path2')
- link3 = self.stub_util.GetOSPath(self._OS_VERSION, 'path3')
+ link1 = self.os_.path('path1')
+ link2 = self.os_.path('path2')
+ link3 = self.os_.path('path3')
self.package1.subpackages['subpackage_1'] = status.MISSING
self.package1.subpackages['subpackage_2'] = status.INSTALLED
self.package2.subpackages['subpackage_2'] = status.LINKED
@@ -266,7 +269,7 @@ class DeviceTest(unittest.TestCase):
self.package2.should_unlink['subpackage_2'] = link3
# Should only actually unlink package2.subpackage_2.
- self.dev.unlink(self._OS_VERSION)
+ self.dev.unlink(self.os_)
self.assertEqual(self.package1.subpackage_status(
'subpackage_1', link1)[0], status.MISSING)
self.assertEqual(self.package1.subpackage_status(
@@ -275,14 +278,14 @@ class DeviceTest(unittest.TestCase):
'subpackage_2', link3)[0], status.INSTALLED)
def test_failed_unlink(self):
- link1 = self.stub_util.GetOSPath(self._OS_VERSION, 'path1')
- link2 = self.stub_util.GetOSPath(self._OS_VERSION, 'path2')
- link3 = self.stub_util.GetOSPath(self._OS_VERSION, 'path3')
+ link1 = self.os_.path('path1')
+ link2 = self.os_.path('path2')
+ link3 = self.os_.path('path3')
self.package2.subpackages['subpackage_2'] = status.LINKED
# Should fail to unlink package2.subpackage_2.
with self.assertRaises(device.PackageUnlinkError):
- self.dev.unlink(self._OS_VERSION)
+ self.dev.unlink(self.os_)
self.assertEqual(self.package1.subpackage_status(
'subpackage_1', link1)[0], status.INSTALLED)
self.assertEqual(self.package1.subpackage_status(
@@ -290,34 +293,6 @@ class DeviceTest(unittest.TestCase):
self.assertEqual(self.package2.subpackage_status(
'subpackage_2', link3)[0], status.LINKED)
- def test_linked(self):
- link1 = self.stub_util.GetOSPath(self._OS_VERSION, 'path1')
- link2 = self.stub_util.GetOSPath(self._OS_VERSION, 'path2')
- link3 = self.stub_util.GetOSPath(self._OS_VERSION, 'path3')
- self.package1.should_link['subpackage_1'] = link1
- self.package1.should_link['subpackage_2'] = link2
- self.package2.should_link['subpackage_2'] = link3
- self.package1.should_unlink['subpackage_1'] = link1
- self.package1.should_unlink['subpackage_2'] = link2
- self.package2.should_unlink['subpackage_2'] = link3
-
- with self.dev.linked(self._OS_VERSION):
- # In context, should be linked.
- self.assertEqual(self.package1.subpackage_status(
- 'subpackage_1', link1)[0], status.LINKED)
- self.assertEqual(self.package1.subpackage_status(
- 'subpackage_2', link2)[0], status.LINKED)
- self.assertEqual(self.package2.subpackage_status(
- 'subpackage_2', link3)[0], status.LINKED)
-
- # Out of context, no longer linked.
- self.assertEqual(self.package1.subpackage_status(
- 'subpackage_1', link1)[0], status.INSTALLED)
- self.assertEqual(self.package1.subpackage_status(
- 'subpackage_2', link2)[0], status.INSTALLED)
- self.assertEqual(self.package2.subpackage_status(
- 'subpackage_2', link3)[0], status.INSTALLED)
-
def test_unrecognized_paths(self):
self.package1.subpackages['subpackage_1'] = status.NOT_INSTALLED
self.package1.subpackages['subpackage_2'] = status.UNRECOGNIZED
@@ -374,9 +349,9 @@ class DeviceTest(unittest.TestCase):
def test_partial_install_with_link(self):
self.package1.downloaded = True
self.package2.downloaded = False
- link1 = self.stub_util.GetOSPath(self._OS_VERSION, 'path1')
- link2 = self.stub_util.GetOSPath(self._OS_VERSION, 'path2')
- link3 = self.stub_util.GetOSPath(self._OS_VERSION, 'path3')
+ link1 = self.os_.path('path1')
+ link2 = self.os_.path('path2')
+ link3 = self.os_.path('path3')
self.package1.should_link['subpackage_1'] = link1
self.package1.should_link['subpackage_2'] = link2
@@ -386,7 +361,7 @@ class DeviceTest(unittest.TestCase):
self.package2.should_download = True
self.assertFalse(self.dev.is_available())
- self.dev.install(auto_accept=True, link_os_version=self._OS_VERSION)
+ self.dev.install(auto_accept=True, link_os=self.os_)
self.assertTrue(self.dev.is_available())
self.assertEqual(self.package1.subpackage_status(
'subpackage_1', self._OS_VERSION)[0], status.LINKED)
@@ -446,7 +421,7 @@ class DeviceTest(unittest.TestCase):
self.assertFalse(self.dev.is_available())
with self.assertRaises(device.PackageLinkError):
- self.dev.install(auto_accept=True, link_os_version=self._OS_VERSION)
+ self.dev.install(auto_accept=True, link_os=self.os_)
# Should still install, just won't be linked.
self.assertTrue(self.dev.is_available())
self.assertNotEqual(self.package1.subpackage_status('subpackage_1')[0],
diff --git a/cli/lib/bsp/operating_system.py b/cli/lib/bsp/operating_system.py
index d672211..7c39692 100644
--- a/cli/lib/bsp/operating_system.py
+++ b/cli/lib/bsp/operating_system.py
@@ -69,6 +69,9 @@ class OperatingSystem(object):
raise VersionError('{} (version must match regex "{}")'.format(
self._version, VERSION_RE))
+ def __repr__(self):
+ return '{}.{}'.format(self.name, self.version)
+
@property
def name(self):
return self._name
diff --git a/cli/lib/commands/bsp/download.py b/cli/lib/commands/bsp/download.py
index 4eeb71e..defc26d 100644
--- a/cli/lib/commands/bsp/download.py
+++ b/cli/lib/commands/bsp/download.py
@@ -63,8 +63,9 @@ class Update(clicommand.Command):
extract_only.keys())
return 1
- os_version = util.GetOSVersion()
- link_os = os_version if args.link else ''
+ os_ = bsp_manifest.operating_systems['brillo']
+ os_version = os_.version
+ link_os = os_ if args.link else ''
try:
device_.install(extract_only, args.accept_licenses, link_os,
diff --git a/cli/lib/commands/product/build.py b/cli/lib/commands/product/build.py
index 9151252..c7e3e0f 100644
--- a/cli/lib/commands/product/build.py
+++ b/cli/lib/commands/product/build.py
@@ -19,12 +19,12 @@
import os
-from bsp import manifest
from cli import clicommand
from commands.product import constants
from core import config
from core import tool
from core import util
+from project import platform
class Build(clicommand.Command):
@@ -55,18 +55,14 @@ class Build(clicommand.Command):
store = config.ProductFileStore(args.product_path)
- # Get the device so the BSP can be linked.
- manifest_ = manifest.Manifest.from_json()
- if not manifest_.is_bsp_available(store.device):
- print ('BSP for "{0}" is not downloaded. '
- 'Please run `bdk bsp download {0}`.'.format(store.device))
- return 1
- device = manifest_.devices[store.device]
-
# Pull the buildtype from the config if it is not overridden.
if args.buildtype is None:
args.buildtype = store.bdk.buildtype
+ # Get the platform so it can be linked.
+ platform_ = platform.Platform(os_name='brillo', board=store.device,
+ build_type=args.buildtype)
+
no_java = 'BRILLO_NO_JAVA=0'
if len(store.bdk.java) and store.bdk.java != '1':
no_java = 'BRILLO_NO_JAVA=1'
@@ -103,7 +99,7 @@ class Build(clicommand.Command):
# TODO(arihc)(b/25952600): Some way to also prevent or at least filter
# metrics for build --help
- with device.linked(util.GetOSVersion()):
+ with platform_.linked():
make.run(full_make_args)
return 0
diff --git a/cli/lib/commands/product/provision.py b/cli/lib/commands/product/provision.py
index 6da7f49..19f3c81 100644
--- a/cli/lib/commands/product/provision.py
+++ b/cli/lib/commands/product/provision.py
@@ -19,12 +19,12 @@
import os
-from bsp import manifest
from cli import clicommand
from commands.product import constants
from core import config
from core import tool
from core import util
+from project import platform
class Provision(clicommand.Command):
@@ -49,13 +49,9 @@ class Provision(clicommand.Command):
store = config.ProductFileStore(args.product_path)
- # Get the device so the BSP can be linked.
- manifest_ = manifest.Manifest.from_json()
- if not manifest_.is_bsp_available(store.device):
- print ('BSP for "{0}" is not downloaded. '
- 'Please run `bdk bsp download {0}`.'.format(store.device))
- return 1
- device = manifest_.devices[store.device]
+ # Get the platform so it can be linked. Build type required but unused.
+ platform_ = platform.Platform(os_name='brillo', board=store.device,
+ build_type=platform.BUILD_TYPE_ENG)
t = tool.BrunchTargetToolWrapper(store, args.product_path,
'provision-device')
@@ -78,6 +74,6 @@ class Provision(clicommand.Command):
return 1
if args.s is not None:
args.args += ['-s', args.s]
- with device.linked(util.GetOSVersion()):
+ with platform_.linked():
t.run(args.args)
return 0
diff --git a/cli/lib/core/build_unittest.py b/cli/lib/core/build_unittest.py
index b18bab0..d50f958 100644
--- a/cli/lib/core/build_unittest.py
+++ b/cli/lib/core/build_unittest.py
@@ -20,7 +20,6 @@
import os
import unittest
-from bsp import device_stub
from core import build
from core import util_stub
from project import platform_stub
@@ -47,12 +46,10 @@ class BuildPlatformTest(unittest.TestCase):
build.util = self.stub_util
build.subprocess = self.stub_subprocess
- self.device = device_stub.StubDevice(
- should_link_version=self._OS_VERSION)
self.platform = platform_stub.StubPlatform(
board=self._BSP, build_type=self._BUILD_TYPE,
os_version=self._OS_VERSION, build_cache=self._OUT_DIR,
- device=self.device)
+ should_link=True)
def test_success(self):
make_command = self.stub_subprocess.AddCommand()
diff --git a/cli/lib/core/image_build_unittest.py b/cli/lib/core/image_build_unittest.py
index f5c8e6b..d15a595 100644
--- a/cli/lib/core/image_build_unittest.py
+++ b/cli/lib/core/image_build_unittest.py
@@ -21,7 +21,6 @@
import copy
import unittest
-from bsp import device_stub
from core import image_build
from core import util_stub
from environment import sysroot_stub
@@ -74,13 +73,11 @@ class BuildImageBase(TestData):
image_build.sysroot = self.stub_sysroot_generator
image_build.util = self.stub_util
- self.device = device_stub.StubDevice(
- should_link_version=self._BRILLO_VERSION)
self.platform = platform_stub.StubPlatform(
os_version=self._BRILLO_VERSION,
- device=self.device, build_cache=self._PLATFORM_DIR,
+ build_cache=self._PLATFORM_DIR,
product_out_cache=self._PRODUCT_DIR,
- os_root=self._OS_ROOT)
+ os_root=self._OS_ROOT, should_link=True)
self.target = target_stub.StubTarget(platform=self.platform)
self.config = config_stub.StubConfig(
artifact_cache=self._ARTIFACT_CACHE_DIR,
@@ -189,7 +186,7 @@ class BaseTests(object):
self.stub_util.arch_is_supported = False
self.stub_subprocess.AddCommand()
# Shouldn't reach the linking point.
- self.device.should_link_version = None
+ self.platform.should_link = False
with self.assertRaises(self.stub_util.HostUnsupportedArchError):
image_build.BuildImage(self.image_type, self.target,
self.config)
diff --git a/cli/lib/core/provision_unittest.py b/cli/lib/core/provision_unittest.py
index ccc8a0e..2485026 100644
--- a/cli/lib/core/provision_unittest.py
+++ b/cli/lib/core/provision_unittest.py
@@ -97,7 +97,7 @@ class ProvisionDeviceTest(unittest.TestCase):
self._PROVISION_DEVICE_PATH,
os.path.join(self.provision_temp_dir, 'provision-device')))
self.stub_os.should_makedirs.append(self.provision_temp_dir)
- self.platform.device.should_link_version = self._OS_VERSION
+ self.platform.should_link = True
def test_call(self):
"""Tests a successful provision-device call."""
@@ -211,7 +211,7 @@ class ProvisionDeviceTest(unittest.TestCase):
self.prepare_os_files()
self.stub_os.path.should_exist.remove(self._FASTBOOT_PATH)
self.stub_subprocess.AddCommand()
-
+ self.platform.should_link = False
with self.assertRaises(provision.MissingBuildError):
provision.provision_device(self.platform)
@@ -220,6 +220,7 @@ class ProvisionDeviceTest(unittest.TestCase):
self.prepare_os_files()
self.stub_os.path.should_exist.remove(self._PROVISION_DEVICE_PATH)
self.stub_subprocess.AddCommand()
+ self.platform.should_link = False
with self.assertRaises(provision.MissingBuildError):
provision.provision_device(self.platform)
diff --git a/cli/lib/core/tool_unittest.py b/cli/lib/core/tool_unittest.py
index a2acb89..9f09093 100644
--- a/cli/lib/core/tool_unittest.py
+++ b/cli/lib/core/tool_unittest.py
@@ -19,7 +19,6 @@
import unittest
-from bsp import device_stub
from core import config
from core import tool
from core import util_stub
@@ -41,8 +40,7 @@ class ToolWrapperTest(unittest.TestCase):
self.platform = platform_stub.StubPlatform(
os_version='12.34', os_root='/source', board='board_name',
- device=device_stub.StubDevice(should_link_version='12.34'),
- build_cache='/build/out')
+ should_link=True, build_cache='/build/out')
def test_run(self):
"""Tests a basic tool run."""
diff --git a/cli/lib/environment/toolchain_util_unittest.py b/cli/lib/environment/toolchain_util_unittest.py
index 2f36401..20dd349 100644
--- a/cli/lib/environment/toolchain_util_unittest.py
+++ b/cli/lib/environment/toolchain_util_unittest.py
@@ -20,7 +20,6 @@
import stat
import unittest
-from bsp import device_stub
from core import util_stub
from environment import toolchain_util
from project import platform_stub
@@ -46,7 +45,7 @@ class ToolchainUtilTest(unittest.TestCase):
self.platform = platform_stub.StubPlatform(
os_version=self.OS_VERSION,
- device=device_stub.StubDevice(arch=self.TARGET_ARCH))
+ device_arch=self.TARGET_ARCH)
def test_generate_toolchain(self):
diff --git a/cli/lib/project/platform.py b/cli/lib/project/platform.py
index 698b089..7b07fb1 100644
--- a/cli/lib/project/platform.py
+++ b/cli/lib/project/platform.py
@@ -62,6 +62,35 @@ class NotDownloadedError(Error):
description = 'Missing download'
+class _LinkContext(object):
+ """A context manager to allow temporary linking of a device to an OS.
+
+ Attributes:
+ platform: The platform to link together.
+ """
+
+ def __init__(self, platform):
+ self.platform = platform
+
+ def __enter__(self):
+ success = False
+ try:
+ self.platform.device.link(self.platform.os)
+ success = True
+ finally:
+ # If something goes wrong, leave unlinked.
+ if not success:
+ self.cleanup()
+
+ def __exit__(self, type_, value_, traceback_):
+ # TODO(b/28028440): Even if you were linked initially, when
+ # exiting the context the links will be removed.
+ self.cleanup()
+
+ def cleanup(self):
+ self.platform.device.unlink(self.platform.os)
+
+
class Platform(object):
"""A (read-only) OS + BSP combination.
@@ -94,6 +123,10 @@ class Platform(object):
raise OsError('unrecognized name "{}" '
'(available OSes: {}).'.format(
os_name, bsp_manifest.operating_systems.keys()))
+ # For now, since we only have one OS version,
+ # fill it in as a default if necessary.
+ if not os_version:
+ os_version = os_.version
if os_.version != os_version:
raise OsError('version {} ({} is the only available '
'version for {}).'.format(
@@ -106,6 +139,10 @@ class Platform(object):
raise BoardError('unrecognized name "{}". Run `bdk bsp list` '
'to see available boards.'.format(
board))
+ # For now, since we only have one device version,
+ # fill it in as a default if necessary.
+ if not board_version:
+ board_version = device.version
if device.version != board_version:
raise BoardError('version {} ({} is the only available '
'version for {}).'.format(
@@ -167,7 +204,15 @@ class Platform(object):
return os.path.join(self._cache_path, *relpath)
def linked(self):
- return self.device.linked(self.os.version)
+ """A context manager for temporary linkage.
+
+ Note: b/28028440: It is a known bug that after exiting the context,
+ the device will be unlinked, whether or not it was linked going in.
+
+ Returns:
+ A context manager within which the BSP and OS will be linked.
+ """
+ return _LinkContext(self)
def verify_downloaded(self):
"""Checks that a platform is downloaded.
diff --git a/cli/lib/project/platform_stub.py b/cli/lib/project/platform_stub.py
index 9f96c3e..4568ddd 100644
--- a/cli/lib/project/platform_stub.py
+++ b/cli/lib/project/platform_stub.py
@@ -21,24 +21,21 @@ import os
from bsp import device_stub
from bsp import operating_system_stub
+from test import stubs
class StubPlatform(object):
"""A Stub for the Platform class."""
def __init__(self, os_name='', os_version='', board='', board_version='',
- build_type='', operating_system=None, device=None, os_root='',
- build_cache='', product_out_cache='', sysroot='', toolchain='',
- cache_dir='', verify_raises=Exception):
+ build_type='', os_root='', device_arch='', build_cache='',
+ product_out_cache='', sysroot='', toolchain='', cache_dir='',
+ should_link=False, verify_raises=Exception):
# Properties.
- self.os = (operating_system or
- operating_system_stub.StubOperatingSystem())
- self.os.name = os_name
- self.os.version = os_version
- self.os.root = os_root
- self.device = device or device_stub.StubDevice()
- self.device.name = board
- self.device.version = board_version
+ self.os = operating_system_stub.StubOperatingSystem(
+ name=os_name, root=os_root, version=os_version)
+ self.device = device_stub.StubDevice(name=board, version=board_version,
+ arch=device_arch)
self.build_type = build_type
self.build_cache = build_cache
self.product_out_cache = product_out_cache
@@ -47,6 +44,7 @@ class StubPlatform(object):
# Helpers.
self.cache_dir = cache_dir
+ self.should_link = should_link
self.verify_raises = verify_raises
@property
@@ -61,7 +59,9 @@ class StubPlatform(object):
return os.path.join(self.cache_dir, *relpath)
def linked(self):
- return self.device.linked(self.os.version)
+ if not self.should_link:
+ raise StubPlatformModule.Error('Not supposed to link platform.')
+ return stubs.StubContextManager()
def verify_downloaded(self):
if self.verify_raises:
diff --git a/cli/lib/project/platform_unittest.py b/cli/lib/project/platform_unittest.py
index 7c021f5..28035a5 100644
--- a/cli/lib/project/platform_unittest.py
+++ b/cli/lib/project/platform_unittest.py
@@ -140,15 +140,10 @@ class PlatformTest(unittest.TestCase):
self.stub_os.path.join(cache_root, 'a', 'nother', 'path'))
def test_link(self):
- self.dev.should_link_version = self._OS_VERSION
+ self.assertFalse(self.dev.is_linked)
with self.platform.linked():
- pass
-
- def test_no_link(self):
- self.dev.should_link_version = None
- with self.assertRaises(device_stub.Error):
- with self.platform.linked():
- pass
+ self.assertTrue(self.dev.is_linked)
+ self.assertFalse(self.dev.is_linked)
def test_verify_downloaded(self):
self.platform.verify_downloaded()