From 9b192015d1e6789bcdc557ab3f537e1a9a31d557 Mon Sep 17 00:00:00 2001
From: Jonathan Maw <jonathan.maw@codethink.co.uk>
Date: Tue, 27 Nov 2018 14:32:20 +0000
Subject: [PATCH] tests: Add tests for guessing element names

This is a part of #222
---
 tests/frontend/source_checkout.py | 19 +++++++++---
 tests/frontend/workspace.py       | 51 ++++++++++++++++++++-----------
 tests/integration/shell.py        | 16 ++++++++--
 3 files changed, 61 insertions(+), 25 deletions(-)

diff --git a/tests/frontend/source_checkout.py b/tests/frontend/source_checkout.py
index 4e7541a310..08230ce5dc 100644
--- a/tests/frontend/source_checkout.py
+++ b/tests/frontend/source_checkout.py
@@ -28,19 +28,28 @@ def generate_remote_import_element(input_path, output_path):
 
 
 @pytest.mark.datafiles(DATA_DIR)
-@pytest.mark.parametrize('with_workspace', [('workspace'), ('no-workspace')])
-def test_source_checkout(datafiles, tmpdir_factory, cli, with_workspace):
+@pytest.mark.parametrize(
+    "with_workspace,guess_element",
+    [(True, True), (True, False), (False, False)],
+    ids=["workspace-guess", "workspace-no-guess", "no-workspace-no-guess"]
+)
+def test_source_checkout(datafiles, cli, tmpdir_factory, with_workspace, guess_element):
     tmpdir = tmpdir_factory.mktemp("")
     project = os.path.join(datafiles.dirname, datafiles.basename)
     checkout = os.path.join(cli.directory, 'source-checkout')
     target = 'checkout-deps.bst'
     workspace = os.path.join(str(tmpdir), 'workspace')
+    elm_cmd = [target] if not guess_element else []
 
-    if with_workspace == "workspace":
-        result = cli.run(project=project, args=['workspace', 'open', '--directory', workspace, target])
+    if with_workspace:
+        ws_cmd = ['-C', workspace]
+        result = cli.run(project=project, args=["workspace", "open", "--directory", workspace, target])
         result.assert_success()
+    else:
+        ws_cmd = []
 
-    result = cli.run(project=project, args=['source-checkout', target, '--deps', 'none', checkout])
+    args = ws_cmd + ['source-checkout', '--deps', 'none'] + elm_cmd + [checkout]
+    result = cli.run(project=project, args=args)
     result.assert_success()
 
     assert os.path.exists(os.path.join(checkout, 'checkout-deps', 'etc', 'buildstream', 'config'))
diff --git a/tests/frontend/workspace.py b/tests/frontend/workspace.py
index baca869bfc..c95eabccdf 100644
--- a/tests/frontend/workspace.py
+++ b/tests/frontend/workspace.py
@@ -616,12 +616,16 @@ def test_list(cli, tmpdir, datafiles):
 @pytest.mark.datafiles(DATA_DIR)
 @pytest.mark.parametrize("kind", repo_kinds)
 @pytest.mark.parametrize("strict", [("strict"), ("non-strict")])
-@pytest.mark.parametrize("call_from", [("project"), ("workspace")])
-def test_build(cli, tmpdir_factory, datafiles, kind, strict, call_from):
+@pytest.mark.parametrize(
+    "from_workspace,guess_element",
+    [(False, False), (True, True), (True, False)],
+    ids=["project-no-guess", "workspace-guess", "workspace-no-guess"])
+def test_build(cli, tmpdir_factory, datafiles, kind, strict, from_workspace, guess_element):
     tmpdir = tmpdir_factory.mktemp('')
     element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, kind, False)
     checkout = os.path.join(str(tmpdir), 'checkout')
-    args_pre = ['-C', workspace] if call_from == "workspace" else []
+    args_dir = ['-C', workspace] if from_workspace else []
+    args_elm = [element_name] if not guess_element else []
 
     # Modify workspace
     shutil.rmtree(os.path.join(workspace, 'usr', 'bin'))
@@ -644,14 +648,14 @@ def test_build(cli, tmpdir_factory, datafiles, kind, strict, call_from):
     # Build modified workspace
     assert cli.get_element_state(project, element_name) == 'buildable'
     assert cli.get_element_key(project, element_name) == "{:?<64}".format('')
-    result = cli.run(project=project, args=args_pre + ['build', element_name])
+    result = cli.run(project=project, args=args_dir + ['build'] + args_elm)
     result.assert_success()
     assert cli.get_element_state(project, element_name) == 'cached'
     assert cli.get_element_key(project, element_name) != "{:?<64}".format('')
 
     # Checkout the result
     result = cli.run(project=project,
-                     args=args_pre + ['checkout', element_name, checkout])
+                     args=args_dir + ['checkout'] + args_elm + [checkout])
     result.assert_success()
 
     # Check that the pony.conf from the modified workspace exists
@@ -1062,29 +1066,36 @@ def test_multiple_failed_builds(cli, tmpdir, datafiles):
 
 @pytest.mark.datafiles(DATA_DIR)
 @pytest.mark.parametrize('subdir', [True, False], ids=["subdir", "no-subdir"])
-def test_external_fetch(cli, datafiles, tmpdir_factory, subdir):
+@pytest.mark.parametrize("guess_element", [True, False], ids=["guess", "no-guess"])
+def test_external_fetch(cli, datafiles, tmpdir_factory, subdir, guess_element):
     # Fetching from a workspace outside a project doesn't fail horribly
     tmpdir = tmpdir_factory.mktemp('')
     element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, "git", False)
+    arg_elm = [element_name] if not guess_element else []
 
     if subdir:
         call_dir = os.path.join(workspace, 'usr')
     else:
         call_dir = workspace
 
-    result = cli.run(project=project, args=['-C', call_dir, 'fetch', element_name])
+    result = cli.run(project=project, args=['-C', call_dir, 'fetch'] + arg_elm)
     result.assert_success()
 
     # We already fetched it by opening the workspace, but we're also checking
     # `bst show` works here
-    assert cli.get_element_state(project, element_name) == 'buildable'
+    result = cli.run(project=project,
+                     args=['-C', call_dir, 'show', '--deps', 'none', '--format', '%{state}'] + arg_elm)
+    result.assert_success()
+    assert result.output.strip() == 'buildable'
 
 
 @pytest.mark.datafiles(DATA_DIR)
-def test_external_push_pull(cli, datafiles, tmpdir_factory):
+@pytest.mark.parametrize("guess_element", [True, False], ids=["guess", "no-guess"])
+def test_external_push_pull(cli, datafiles, tmpdir_factory, guess_element):
     # Pushing and pulling to/from an artifact cache works from an external workspace
     tmpdir = tmpdir_factory.mktemp('')
     element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, "git", False)
+    arg_elm = [element_name] if not guess_element else []
 
     with create_artifact_share(os.path.join(str(tmpdir), 'artifactshare')) as share:
         result = cli.run(project=project, args=['-C', workspace, 'build', element_name])
@@ -1094,22 +1105,24 @@ def test_external_push_pull(cli, datafiles, tmpdir_factory):
             'artifacts': {'url': share.repo, 'push': True}
         })
 
-        result = cli.run(project=project, args=['-C', workspace, 'push', element_name])
+        result = cli.run(project=project, args=['-C', workspace, 'push'] + arg_elm)
         result.assert_success()
 
-        result = cli.run(project=project, args=['-C', workspace, 'pull', '--deps', 'all', element_name])
+        result = cli.run(project=project, args=['-C', workspace, 'pull', '--deps', 'all'] + arg_elm)
         result.assert_success()
 
 
 @pytest.mark.datafiles(DATA_DIR)
-def test_external_track(cli, datafiles, tmpdir_factory):
+@pytest.mark.parametrize("guess_element", [True, False], ids=["guess", "no-guess"])
+def test_external_track(cli, datafiles, tmpdir_factory, guess_element):
     # Tracking does not get horribly confused
     tmpdir = tmpdir_factory.mktemp('')
     element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, "git", True)
+    arg_elm = [element_name] if not guess_element else []
 
     # The workspace is necessarily already tracked, so we only care that
     # there's no weird errors.
-    result = cli.run(project=project, args=['-C', workspace, 'track', element_name])
+    result = cli.run(project=project, args=['-C', workspace, 'track'] + arg_elm)
     result.assert_success()
 
 
@@ -1147,15 +1160,17 @@ def test_external_close_other(cli, datafiles, tmpdir_factory):
 
 
 @pytest.mark.datafiles(DATA_DIR)
-def test_external_close_self(cli, datafiles, tmpdir_factory):
+@pytest.mark.parametrize("guess_element", [True, False], ids=["guess", "no-guess"])
+def test_external_close_self(cli, datafiles, tmpdir_factory, guess_element):
     # From inside an external workspace, close it
     tmpdir1 = tmpdir_factory.mktemp('')
     tmpdir2 = tmpdir_factory.mktemp('')
     # Making use of the assumption that it's the same project in both invocations of open_workspace
     alpha_element, project, alpha_workspace = open_workspace(cli, tmpdir1, datafiles, "git", False, suffix="-alpha")
     beta_element, _, beta_workspace = open_workspace(cli, tmpdir2, datafiles, "git", False, suffix="-beta")
+    arg_elm = [alpha_element] if not guess_element else []
 
-    result = cli.run(project=project, args=['-C', alpha_workspace, 'workspace', 'close', alpha_element])
+    result = cli.run(project=project, args=['-C', alpha_workspace, 'workspace', 'close'] + arg_elm)
     result.assert_success()
 
 
@@ -1172,11 +1187,13 @@ def test_external_reset_other(cli, datafiles, tmpdir_factory):
 
 
 @pytest.mark.datafiles(DATA_DIR)
-def test_external_reset_self(cli, datafiles, tmpdir):
+@pytest.mark.parametrize("guess_element", [True, False], ids=["guess", "no-guess"])
+def test_external_reset_self(cli, datafiles, tmpdir, guess_element):
     element, project, workspace = open_workspace(cli, tmpdir, datafiles, "git", False)
+    arg_elm = [element] if not guess_element else []
 
     # Command succeeds
-    result = cli.run(project=project, args=['-C', workspace, 'workspace', 'reset', element])
+    result = cli.run(project=project, args=['-C', workspace, 'workspace', 'reset'] + arg_elm)
     result.assert_success()
 
     # Successive commands still work (i.e. .bstproject.yaml hasn't been deleted)
diff --git a/tests/integration/shell.py b/tests/integration/shell.py
index 1cec218183..983cab6b54 100644
--- a/tests/integration/shell.py
+++ b/tests/integration/shell.py
@@ -358,13 +358,22 @@ def test_integration_devices(cli, tmpdir, datafiles):
 # Test that a shell can be opened from an external workspace
 @pytest.mark.datafiles(DATA_DIR)
 @pytest.mark.parametrize("build_shell", [("build"), ("nobuild")])
+@pytest.mark.parametrize("guess_element", [True, False], ids=["guess", "no-guess"])
 @pytest.mark.skipif(IS_LINUX and not HAVE_BWRAP, reason='Only available with bubblewrap on Linux')
-def test_integration_external_workspace(cli, tmpdir_factory, datafiles, build_shell):
+def test_integration_external_workspace(cli, tmpdir_factory, datafiles, build_shell, guess_element):
     tmpdir = tmpdir_factory.mktemp("")
     project = os.path.join(datafiles.dirname, datafiles.basename)
     element_name = 'autotools/amhello.bst'
     workspace_dir = os.path.join(str(tmpdir), 'workspace')
 
+    if guess_element:
+        # Mutate the project.conf to use a default shell command
+        project_file = os.path.join(project, 'project.conf')
+        config_text = "shell:\n"\
+                      "  command: ['true']\n"
+        with open(project_file, 'a') as f:
+            f.write(config_text)
+
     result = cli.run(project=project, args=[
         'workspace', 'open', '--directory', workspace_dir, element_name
     ])
@@ -373,9 +382,10 @@ def test_integration_external_workspace(cli, tmpdir_factory, datafiles, build_sh
     result = cli.run(project=project, args=['-C', workspace_dir, 'build', element_name])
     result.assert_success()
 
-    command = ['shell']
+    command = ['-C', workspace_dir, 'shell']
     if build_shell == 'build':
         command.append('--build')
-    command.extend([element_name, '--', 'true'])
+    if not guess_element:
+        command.extend([element_name, '--', 'true'])
     result = cli.run(project=project, cwd=workspace_dir, args=command)
     result.assert_success()
-- 
GitLab