blob: dd7977e76c0abe9b8b64d21b50b8606334ac34c2 [file] [log] [blame]
#
# Copyright (C) 2018 Codethink Limited
# Copyright (C) 2019 Bloomberg Finance LP
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
#
# Pylint doesn't play well with fixtures and dependency injection from pytest
# pylint: disable=redefined-outer-name
import os
import shutil
import pytest
from buildstream import _yaml
from .. import create_repo
from .. import cli # pylint: disable=unused-import
from .utils import kind # pylint: disable=unused-import
# Project directory
TOP_DIR = os.path.dirname(os.path.realpath(__file__))
DATA_DIR = os.path.join(TOP_DIR, 'project')
class WorkspaceCreator():
def __init__(self, cli, tmpdir, datafiles, project_path=None):
self.cli = cli
self.tmpdir = tmpdir
self.datafiles = datafiles
if not project_path:
project_path = str(datafiles)
else:
shutil.copytree(str(datafiles), project_path)
self.project_path = project_path
self.bin_files_path = os.path.join(project_path, 'files', 'bin-files')
self.workspace_cmd = os.path.join(self.project_path, 'workspace_cmd')
def create_workspace_element(self, kind, track, suffix='', workspace_dir=None,
element_attrs=None):
element_name = 'workspace-test-{}{}.bst'.format(kind, suffix)
element_path = os.path.join(self.project_path, 'elements')
if not workspace_dir:
workspace_dir = os.path.join(self.workspace_cmd, element_name)
if workspace_dir[-4:] == '.bst':
workspace_dir = workspace_dir[:-4]
# Create our repo object of the given source type with
# the bin files, and then collect the initial ref.
repo = create_repo(kind, str(self.tmpdir))
ref = repo.create(self.bin_files_path)
if track:
ref = None
# Write out our test target
element = {
'kind': 'import',
'sources': [
repo.source_config(ref=ref)
]
}
if element_attrs:
element = {**element, **element_attrs}
_yaml.roundtrip_dump(element,
os.path.join(element_path, element_name))
return element_name, element_path, workspace_dir
def create_workspace_elements(self, kinds, track, suffixs=None, workspace_dir_usr=None,
element_attrs=None):
element_tuples = []
if suffixs is None:
suffixs = ['', ] * len(kinds)
else:
if len(suffixs) != len(kinds):
raise "terable error"
for suffix, kind in zip(suffixs, kinds):
element_name, _, workspace_dir = \
self.create_workspace_element(kind, track, suffix, workspace_dir_usr,
element_attrs)
element_tuples.append((element_name, workspace_dir))
# Assert that there is no reference, a track & fetch is needed
states = self.cli.get_element_states(self.project_path, [
e for e, _ in element_tuples
])
if track:
assert not any(states[e] != 'no reference' for e, _ in element_tuples)
else:
assert not any(states[e] != 'fetch needed' for e, _ in element_tuples)
return element_tuples
def open_workspaces(self, kinds, track, suffixs=None, workspace_dir=None,
element_attrs=None, no_checkout=False):
element_tuples = self.create_workspace_elements(kinds, track, suffixs, workspace_dir,
element_attrs)
os.makedirs(self.workspace_cmd, exist_ok=True)
# Now open the workspace, this should have the effect of automatically
# tracking & fetching the source from the repo.
args = ['workspace', 'open']
if track:
args.append('--track')
if no_checkout:
args.append('--no-checkout')
if workspace_dir is not None:
assert len(element_tuples) == 1, "test logic error"
_, workspace_dir = element_tuples[0]
args.extend(['--directory', workspace_dir])
args.extend([element_name for element_name, workspace_dir_suffix in element_tuples])
result = self.cli.run(cwd=self.workspace_cmd, project=self.project_path, args=args)
result.assert_success()
if not no_checkout:
# Assert that we are now buildable because the source is now cached.
states = self.cli.get_element_states(self.project_path, [
e for e, _ in element_tuples
])
assert not any(states[e] != 'buildable' for e, _ in element_tuples)
# Check that the executable hello file is found in each workspace
for _, workspace in element_tuples:
filename = os.path.join(workspace, 'usr', 'bin', 'hello')
assert os.path.exists(filename)
return element_tuples
def open_workspace(cli, tmpdir, datafiles, kind, track, suffix='', workspace_dir=None,
project_path=None, element_attrs=None, no_checkout=False):
workspace_object = WorkspaceCreator(cli, tmpdir, datafiles, project_path)
workspaces = workspace_object.open_workspaces((kind, ), track, (suffix, ), workspace_dir,
element_attrs, no_checkout)
assert len(workspaces) == 1
element_name, workspace = workspaces[0]
return element_name, workspace_object.project_path, workspace
@pytest.mark.datafiles(DATA_DIR)
def test_open(cli, tmpdir, datafiles, kind):
open_workspace(cli, tmpdir, datafiles, kind, False)