Tristan Van Berkom pushed to branch tristan/fix-artifact-config-crash at BuildStream / buildstream
Commits:
- 
0c426cb4
by Tristan Van Berkom at 2018-09-18T09:37:26Z
 - 
4a869664
by Tristan Van Berkom at 2018-09-18T09:37:26Z
 
5 changed files:
- buildstream/_artifactcache/artifactcache.py
 - tests/artifactcache/config.py
 - + tests/artifactcache/missing-certs/certificates/client.crt
 - + tests/artifactcache/missing-certs/certificates/client.key
 - + tests/artifactcache/missing-certs/element.bst
 
Changes:
| ... | ... | @@ -51,7 +51,7 @@ class ArtifactCacheSpec(namedtuple('ArtifactCacheSpec', 'url push server_cert cl | 
| 51 | 51 | 
         url = _yaml.node_get(spec_node, str, 'url')
 | 
| 52 | 52 | 
         push = _yaml.node_get(spec_node, bool, 'push', default_value=False)
 | 
| 53 | 53 | 
         if not url:
 | 
| 54 | 
-            provenance = _yaml.node_get_provenance(spec_node)
 | 
|
| 54 | 
+            provenance = _yaml.node_get_provenance(spec_node, 'url')
 | 
|
| 55 | 55 | 
             raise LoadError(LoadErrorReason.INVALID_DATA,
 | 
| 56 | 56 | 
                             "{}: empty artifact cache URL".format(provenance))
 | 
| 57 | 57 | 
 | 
| ... | ... | @@ -67,6 +67,16 @@ class ArtifactCacheSpec(namedtuple('ArtifactCacheSpec', 'url push server_cert cl | 
| 67 | 67 | 
         if client_cert and basedir:
 | 
| 68 | 68 | 
             client_cert = os.path.join(basedir, client_cert)
 | 
| 69 | 69 | 
 | 
| 70 | 
+        if client_key and not client_cert:
 | 
|
| 71 | 
+            provenance = _yaml.node_get_provenance(spec_node, 'client-key')
 | 
|
| 72 | 
+            raise LoadError(LoadErrorReason.INVALID_DATA,
 | 
|
| 73 | 
+                            "{}: 'client-key' was specified without 'client-cert'".format(provenance))
 | 
|
| 74 | 
+  | 
|
| 75 | 
+        if client_cert and not client_key:
 | 
|
| 76 | 
+            provenance = _yaml.node_get_provenance(spec_node, 'client-cert')
 | 
|
| 77 | 
+            raise LoadError(LoadErrorReason.INVALID_DATA,
 | 
|
| 78 | 
+                            "{}: 'client-cert' was specified without 'client-key'".format(provenance))
 | 
|
| 79 | 
+  | 
|
| 70 | 80 | 
         return ArtifactCacheSpec(url, push, server_cert, client_key, client_cert)
 | 
| 71 | 81 | 
 | 
| 72 | 82 | 
 | 
| ... | ... | @@ -9,8 +9,12 @@ from buildstream._context import Context | 
| 9 | 9 | 
 from buildstream._project import Project
 | 
| 10 | 10 | 
 from buildstream.utils import _deduplicate
 | 
| 11 | 11 | 
 from buildstream import _yaml
 | 
| 12 | 
+from buildstream._exceptions import ErrorDomain, LoadErrorReason
 | 
|
| 12 | 13 | 
 | 
| 14 | 
+from tests.testutils.runcli import cli
 | 
|
| 13 | 15 | 
 | 
| 16 | 
+  | 
|
| 17 | 
+DATA_DIR = os.path.dirname(os.path.realpath(__file__))
 | 
|
| 14 | 18 | 
 cache1 = ArtifactCacheSpec(url='https://example.com/cache1', push=True)
 | 
| 15 | 19 | 
 cache2 = ArtifactCacheSpec(url='https://example.com/cache2', push=False)
 | 
| 16 | 20 | 
 cache3 = ArtifactCacheSpec(url='https://example.com/cache3', push=False)
 | 
| ... | ... | @@ -106,3 +110,33 @@ def test_artifact_cache_precedence(tmpdir, override_caches, project_caches, user | 
| 106 | 110 | 
     # Verify that it was correctly read.
 | 
| 107 | 111 | 
     expected_cache_specs = list(_deduplicate(itertools.chain(override_caches, project_caches, user_caches)))
 | 
| 108 | 112 | 
     assert parsed_cache_specs == expected_cache_specs
 | 
| 113 | 
+  | 
|
| 114 | 
+  | 
|
| 115 | 
+# Assert that if either the client key or client cert is specified
 | 
|
| 116 | 
+# without specifying it's counterpart, we get a comprehensive LoadError
 | 
|
| 117 | 
+# instead of an unhandled exception.
 | 
|
| 118 | 
+@pytest.mark.datafiles(DATA_DIR)
 | 
|
| 119 | 
+@pytest.mark.parametrize('config_key, config_value', [
 | 
|
| 120 | 
+    ('client-cert', 'client.crt'),
 | 
|
| 121 | 
+    ('client-key', 'client.key')
 | 
|
| 122 | 
+])
 | 
|
| 123 | 
+def test_missing_certs(cli, datafiles, config_key, config_value):
 | 
|
| 124 | 
+    project = os.path.join(datafiles.dirname, datafiles.basename, 'missing-certs')
 | 
|
| 125 | 
+  | 
|
| 126 | 
+    project_conf = {
 | 
|
| 127 | 
+        'name': 'test',
 | 
|
| 128 | 
+  | 
|
| 129 | 
+        'artifacts': {
 | 
|
| 130 | 
+            'url': 'https://cache.example.com:12345',
 | 
|
| 131 | 
+            'push': 'true',
 | 
|
| 132 | 
+            config_key: config_value
 | 
|
| 133 | 
+        }
 | 
|
| 134 | 
+    }
 | 
|
| 135 | 
+    project_conf_file = os.path.join (project, 'project.conf')
 | 
|
| 136 | 
+    _yaml.dump(project_conf, project_conf_file)
 | 
|
| 137 | 
+  | 
|
| 138 | 
+    # Use `pull` here to ensure we try to initialize the remotes, triggering the error
 | 
|
| 139 | 
+    #
 | 
|
| 140 | 
+    # This does not happen for a simple `bst show`.
 | 
|
| 141 | 
+    result = cli.run(project=project, args=['pull', 'element.bst'])
 | 
|
| 142 | 
+    result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.INVALID_DATA)
 | 
| 1 | 
+kind: autotools
 | 
