| # Copyright 2017 The Cobalt Authors. All Rights Reserved. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| """Base platform build configuration.""" |
| |
| import importlib.machinery |
| import importlib.util |
| import inspect |
| import logging |
| import os |
| |
| from starboard.build.application_configuration import ApplicationConfiguration |
| import starboard_configuration # Should be at root of source tree |
| |
| |
| def _GetApplicationConfigurationClass(application_path): |
| """Gets the ApplicationConfiguration class from the given path.""" |
| if not os.path.isdir(application_path): |
| return None |
| |
| application_configuration_path = os.path.join(application_path, |
| 'configuration.py') |
| if not os.path.isfile(application_configuration_path): |
| return None |
| |
| loader = importlib.machinery.SourceFileLoader('application_configuration', |
| application_configuration_path) |
| spec = importlib.util.spec_from_file_location( |
| 'application_configuration', |
| application_configuration_path, |
| loader=loader) |
| application_configuration = importlib.util.module_from_spec(spec) |
| loader.exec_module(application_configuration) |
| for name, cls in inspect.getmembers(application_configuration): |
| if not inspect.isclass(cls): |
| continue |
| if issubclass(cls, ApplicationConfiguration): |
| logging.debug('Found ApplicationConfiguration: %s in %s', name, |
| application_configuration_path) |
| return cls |
| |
| return None |
| |
| |
| class PlatformConfiguration(object): |
| """Base platform build configuration class for all Starboard platforms. |
| |
| Should be derived by platform specific configurations. |
| """ |
| |
| def __init__(self, platform_name): |
| self._platform_name = platform_name |
| self._directory = os.path.realpath(os.path.dirname(__file__)) |
| self._application_configuration = None |
| self._application_configuration_search_path = [self._directory] |
| |
| def GetName(self): |
| """Returns the platform name.""" |
| return self._platform_name |
| |
| def GetDirectory(self): |
| """Returns the directory of the platform configuration.""" |
| return self._directory |
| |
| # This happens post-construction to maintain compatibility with legacy |
| # configurations. |
| # TODO: Find some other way to do this. |
| def SetDirectory(self, directory): |
| """Sets the directory of the platform configuration.""" |
| try: |
| i = self._application_configuration_search_path.index(self._directory) |
| self._application_configuration_search_path.pop(i) |
| except ValueError: |
| i = 0 |
| self._directory = directory |
| self._application_configuration_search_path.insert(i, self._directory) |
| |
| def AppendApplicationConfigurationPath(self, path): |
| """Appends a path to search for ApplicationConfiguration modules.""" |
| self._application_configuration_search_path.append(path) |
| |
| def GetApplicationConfiguration(self, application_name): |
| """Get the instance of ApplicationConfiguration for this app, if any. |
| |
| Looks for a class deriving from ApplicationConfiguration defined for |
| this platform. If it finds one, this function will load, instantiate, and |
| return the configuration. Otherwise, it will return None. |
| |
| Args: |
| application_name: The name of the application to load, in a canonical |
| filesystem-friendly form. |
| |
| Returns: |
| An instance of ApplicationConfiguration defined for the application being |
| loaded. |
| """ |
| if not self._application_configuration: |
| application_path = os.path.join(self.GetDirectory(), application_name) |
| for directory in self._application_configuration_search_path: |
| configuration_path = os.path.join(directory, application_name) |
| logging.debug('Searching for ApplicationConfiguration in %s', |
| configuration_path) |
| configuration_class = _GetApplicationConfigurationClass( |
| configuration_path) |
| if configuration_class: |
| logging.info( |
| 'Using platform-specific ApplicationConfiguration for ' |
| '%s.', application_name) |
| break |
| |
| if not configuration_class: |
| configuration_class = starboard_configuration.APPLICATIONS.get( |
| application_name) |
| if configuration_class: |
| logging.info('Using default ApplicationConfiguration for %s.', |
| application_name) |
| |
| if not configuration_class: |
| logging.info('Using base ApplicationConfiguration.') |
| configuration_class = ApplicationConfiguration |
| |
| self._application_configuration = configuration_class( |
| self, application_name, application_path) |
| |
| assert self._application_configuration |
| return self._application_configuration |
| |
| def GetLauncherPath(self): |
| """Gets the path to the launcher module for this platform.""" |
| return self.GetDirectory() |
| |
| def GetLauncher(self): |
| """Gets the module used to launch applications on this platform.""" |
| module_path = os.path.abspath( |
| os.path.join(self.GetLauncherPath(), 'launcher.py')) |
| try: |
| loader = importlib.machinery.SourceFileLoader('launcher', module_path) |
| spec = importlib.util.spec_from_file_location( |
| 'launcher', module_path, loader=loader) |
| launcher = importlib.util.module_from_spec(spec) |
| loader.exec_module(launcher) |
| return launcher |
| except (IOError, ImportError, RuntimeError) as error: |
| logging.error('Unable to load launcher module from %s.', module_path) |
| logging.error(error) |
| return None |
| |
| def GetTestEnvVariables(self): |
| """Gets a dict of environment variables needed by unit test binaries.""" |
| return {} |
| |
| def GetTestTargets(self): |
| """Gets all tests to be run in a unit test run. |
| |
| Returns: |
| A list of strings of test target names. |
| """ |
| # TODO(b/292007482): Replace static list with gn query. |
| return [ |
| 'common_test', |
| 'cwrappers_test', |
| 'eztime_test', |
| 'nplb', |
| # TODO(b/292138589): Fails on various linux configs. |
| # 'nplb_evergreen_compat_tests', |
| 'player_filter_tests', |
| 'starboard_platform_tests', |
| ] |
| |
| def GetTestBlackBoxTargets(self): |
| """Gets all tests to be run in a black box test run. |
| |
| Returns: |
| A list of strings of black box test target names. |
| """ |
| return [] |