From e09c6cb8cd4d958d01785ccfe7c1b02d791fcb72 Mon Sep 17 00:00:00 2001 From: Kris De Volder Date: Wed, 14 Dec 2016 09:09:41 -0800 Subject: [PATCH] Add basic support for resource-types attribute Also some cleanups in test code etc. --- .../util/SimpleTextDocumentService.java | 1 - .../yaml/schema/CachingSchemaContext.java | 10 + .../concourse/ConcourseLanguageServer.java | 11 +- .../vscode/concourse/PipelineYmlSchema.java | 26 +- .../desc/Pipeline/resource_types.html | 52 ++ ....java => ConcourseLanguageServerTest.java} | 32 +- .../manifest/yaml/ManifestYamlEditorTest.java | 493 ------------------ .../manifest/yaml/PipelineYamlEditorTest.java | 258 +++++++++ ...maTest.java => PipelineYmlSchemaTest.java} | 36 +- .../resources/workspace}/another-pipeline.yml | 0 .../src/test/resources/workspace/manifest.yml | 5 - .../test/resources/workspace}/pipeline.yml | 0 .../workspace}/tasks/build-stuff.yml | 0 .../tasks/build-vscode-extensions.sh | 0 .../tasks/build-vscode-extensions.yml | 0 .../workspace}/tasks/build-website.sh | 0 .../workspace}/tasks/build-website.yml | 0 .../resources/workspace}/tasks/test-stuff.yml | 0 .../test/examples/destroy-pipeline.sh | 4 - .../test/examples/docker/Dockerfile | 17 - .../test/examples/docker/npmrc | 1 - .../test/examples/set-pipeline.sh | 3 - 22 files changed, 348 insertions(+), 601 deletions(-) create mode 100644 vscode-extensions/vscode-concourse/src/main/resources/desc/Pipeline/resource_types.html rename vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/{ManifestYamlLanguageServerTest.java => ConcourseLanguageServerTest.java} (52%) delete mode 100644 vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlEditorTest.java create mode 100644 vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/PipelineYamlEditorTest.java rename vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/{ManifestYmlSchemaTest.java => PipelineYmlSchemaTest.java} (87%) rename vscode-extensions/vscode-concourse/{test/examples => src/test/resources/workspace}/another-pipeline.yml (100%) delete mode 100644 vscode-extensions/vscode-concourse/src/test/resources/workspace/manifest.yml rename vscode-extensions/vscode-concourse/{test/examples => src/test/resources/workspace}/pipeline.yml (100%) rename vscode-extensions/vscode-concourse/{test/examples => src/test/resources/workspace}/tasks/build-stuff.yml (100%) rename vscode-extensions/vscode-concourse/{test/examples => src/test/resources/workspace}/tasks/build-vscode-extensions.sh (100%) rename vscode-extensions/vscode-concourse/{test/examples => src/test/resources/workspace}/tasks/build-vscode-extensions.yml (100%) rename vscode-extensions/vscode-concourse/{test/examples => src/test/resources/workspace}/tasks/build-website.sh (100%) rename vscode-extensions/vscode-concourse/{test/examples => src/test/resources/workspace}/tasks/build-website.yml (100%) rename vscode-extensions/vscode-concourse/{test/examples => src/test/resources/workspace}/tasks/test-stuff.yml (100%) delete mode 100755 vscode-extensions/vscode-concourse/test/examples/destroy-pipeline.sh delete mode 100644 vscode-extensions/vscode-concourse/test/examples/docker/Dockerfile delete mode 100644 vscode-extensions/vscode-concourse/test/examples/docker/npmrc delete mode 100755 vscode-extensions/vscode-concourse/test/examples/set-pipeline.sh diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleTextDocumentService.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleTextDocumentService.java index b5daadcaf..3745e10ac 100644 --- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleTextDocumentService.java +++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleTextDocumentService.java @@ -65,7 +65,6 @@ public class SimpleTextDocumentService implements TextDocumentService { this.server = server; } - public synchronized void onHover(HoverHandler h) { Assert.isNull("A hover handler is already set, multiple handlers not supported yet", hoverHandler); this.hoverHandler = h; diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/CachingSchemaContext.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/CachingSchemaContext.java index bb1dc4b27..cd32f5ebf 100644 --- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/CachingSchemaContext.java +++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/CachingSchemaContext.java @@ -1,3 +1,13 @@ +/******************************************************************************* + * Copyright (c) 2015, 2016 Pivotal, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ package org.springframework.ide.vscode.commons.yaml.schema; import java.util.Set; diff --git a/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/ConcourseLanguageServer.java b/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/ConcourseLanguageServer.java index a4b38904b..84b3f2060 100644 --- a/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/ConcourseLanguageServer.java +++ b/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/ConcourseLanguageServer.java @@ -1,9 +1,5 @@ package org.springframework.ide.vscode.concourse; -import java.util.Collection; - -import javax.inject.Provider; - import org.eclipse.lsp4j.CompletionOptions; import org.eclipse.lsp4j.ServerCapabilities; import org.eclipse.lsp4j.TextDocumentSyncKind; @@ -23,19 +19,14 @@ import org.springframework.ide.vscode.commons.yaml.completion.YamlAssistContextP import org.springframework.ide.vscode.commons.yaml.completion.YamlCompletionEngine; import org.springframework.ide.vscode.commons.yaml.hover.YamlHoverInfoProvider; import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaBasedReconcileEngine; -import org.springframework.ide.vscode.commons.yaml.schema.YValueHint; import org.springframework.ide.vscode.commons.yaml.schema.YamlSchema; import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureProvider; import org.yaml.snakeyaml.Yaml; -import com.google.common.collect.ImmutableList; - public class ConcourseLanguageServer extends SimpleLanguageServer { - private static final Provider> NO_BUILDPACKS = () -> ImmutableList.of(); - private Yaml yaml = new Yaml(); - private YamlSchema schema = new PipelineYmlSchema(NO_BUILDPACKS); + private YamlSchema schema = new PipelineYmlSchema(); public ConcourseLanguageServer() { diff --git a/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java b/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java index a48fa863b..19d480c56 100644 --- a/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java +++ b/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java @@ -10,10 +10,6 @@ *******************************************************************************/ package org.springframework.ide.vscode.concourse; -import java.util.Collection; - -import javax.inject.Provider; - import org.springframework.ide.vscode.commons.util.Renderable; import org.springframework.ide.vscode.commons.util.Renderables; import org.springframework.ide.vscode.commons.yaml.schema.YType; @@ -21,7 +17,6 @@ import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory; import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory.YAtomicType; import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory.YBeanType; import org.springframework.ide.vscode.commons.yaml.schema.YTypeUtil; -import org.springframework.ide.vscode.commons.yaml.schema.YValueHint; import org.springframework.ide.vscode.commons.yaml.schema.YamlSchema; /** @@ -34,7 +29,7 @@ public class PipelineYmlSchema implements YamlSchema { private final YTypeFactory f = new YTypeFactory(); - public PipelineYmlSchema(Provider> buildpackProvider) { + public PipelineYmlSchema() { TYPE_UTIL = f.TYPE_UTIL; // define schema types @@ -52,20 +47,22 @@ public class PipelineYmlSchema implements YamlSchema { YAtomicType t_version = f.yatomic("Version"); t_version.addHints("latest", "every"); + + YAtomicType t_image_type = f.yatomic("ImageType"); + t_image_type.addHints("docker_image"); YAtomicType t_resource_type = f.yatomic("ResourceType"); t_resource_type.addHints( + f.hint("archive", "archive - The 'archive' resource can fetch and extract .tar.gz archives."), f.hint("git", "git - The 'git' resource can pull and push to git repositories"), - f.hint("time", "time - The 'time' resource can start jobs on a schedule or timestamp outputs."), f.hint("s3", "s3 - The 's3' resource can fetch from and upload to S3 buckets."), - f.hint("archive", "archive - The archive resource can fetch and extract .tar.gz archives.") + f.hint("semver", "semver - The 'semver' resource can set or bump version numbers."), + f.hint("time", "time - The 'time' resource can start jobs on a schedule or timestamp outputs."), + f.hint("docker-image", "docker-image - The 'docker-image' resource can fetch, build, and push Docker images") //TODO: add more resource types and descriptions. // -// The semver resource can set or bump version numbers. -// // The github-release resource can fetch and publish versioned GitHub resources. // -// The docker-image resource can fetch, build, and push Docker images // // The tracker resource can deliver stories and bugs on Pivotal Tracker // @@ -122,9 +119,16 @@ public class PipelineYmlSchema implements YamlSchema { prop(job, "public", t_boolean); prop(job, "disable_manual_trigger", t_boolean); prop(job, "plan", f.yseq(step)); + + YType resource_type_def = f.ybean("ResourceTypeDef", + f.yprop("name", t_ne_string), + f.yprop("type", t_image_type), + f.yprop("source", t_any) + ); prop(TOPLEVEL_TYPE, "resources", f.yseq(resource)); prop(TOPLEVEL_TYPE, "jobs", f.yseq(job)); + prop(TOPLEVEL_TYPE, "resource_types", f.yseq(resource_type_def)); } diff --git a/vscode-extensions/vscode-concourse/src/main/resources/desc/Pipeline/resource_types.html b/vscode-extensions/vscode-concourse/src/main/resources/desc/Pipeline/resource_types.html new file mode 100644 index 000000000..002a82b12 --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/main/resources/desc/Pipeline/resource_types.html @@ -0,0 +1,52 @@ +

Additional resource types used by your pipeline

+ +

Each resource in a pipeline has a type. The resource's type determines +what versions are detected, the bits that are fetched when used for a +get step, and the side effect that occurs when used for a +put step.

Out of the box, Concourse comes with a few resource types to cover common CI +use cases like dealing with Git repositories and S3 buckets.

Beyond these core types, each pipeline can configure its own custom types by +specifying resource_types at the top level. Each custom resource type is +itself defined as a resource that provides the container image for the custom +resource type (see Implementing a Resource). You will almost always +be using the +docker-image +resource type when doing this.

The following example extends a Concourse pipeline to support use of the +pull-request +resource type and then uses it within the pipeline:

resource_types:
+- name: pull-request
+  type: docker-image
+  source:
+    repository: jtarchie/pr
+
+resources:
+- name: atomy-pr
+  type: pull-request
+  source:
+    repo: vito/atomy
+    access_token: {{access-token}}
+
+jobs:
+- name: atomy-pr-unit
+  plan:
+  - get: atomy-pr
+  - put: atomy-pr
+    params:
+      path: atomy-pr
+      status: pending
+  - task: unit
+    file: atomy-pr/ci/unit.yml
+    on_success:
+      put: atomy-pr
+      params:
+        path: atomy-pr
+        status: success
+    on_failure:
+      put: atomy-pr
+      params:
+        path: atomy-pr
+        status: failure

Custom resource types can override the core resource types, and can be defined +in terms of each other. Also, a custom resource type can use the core type that +it's overriding. This is useful if you want to e.g. provide your own custom +docker-image resource, by overriding the core one (and using it one last +time for the override itself), and then using it for all other custom resource +types.

\ No newline at end of file diff --git a/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServerTest.java b/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/ConcourseLanguageServerTest.java similarity index 52% rename from vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServerTest.java rename to vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/ConcourseLanguageServerTest.java index 53231a920..6333dd670 100644 --- a/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServerTest.java +++ b/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/ConcourseLanguageServerTest.java @@ -12,10 +12,10 @@ import org.junit.Test; import org.springframework.ide.vscode.concourse.ConcourseLanguageServer; import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness; -public class ManifestYamlLanguageServerTest { +public class ConcourseLanguageServerTest { public static File getTestResource(String name) throws URISyntaxException { - return Paths.get(ManifestYamlLanguageServerTest.class.getResource(name).toURI()).toFile(); + return Paths.get(ConcourseLanguageServerTest.class.getResource(name).toURI()).toFile(); } @Test @@ -32,34 +32,6 @@ public class ManifestYamlLanguageServerTest { assertExpectedInitResult(harness.intialize(workspaceRoot)); } -// @Test public void completions() throws Exception { -// LanguageServerHarness harness = new LanguageServerHarness(ManifestYamlLanguageServer::new); -// -// File workspaceRoot = getTestResource("/workspace/"); -// assertExpectedInitResult(harness.intialize(workspaceRoot)); -// -// TextDocumentInfo doc = harness.openDocument(getTestResource("/workspace/testfile.yml")); -// -// CompletionList completions = harness.getCompletions(doc, doc.positionOf("foo")); -// assertThat(completions.isIncomplete()).isFalse(); -// assertThat(completions.getItems()) -// .extracting(CompletionItem::getLabel) -// .containsExactly("TypeScript", "JavaScript"); -// -// List resolved = harness.resolveCompletions(completions); -// assertThat(resolved) -// .extracting(CompletionItem::getLabel) -// .containsExactly("TypeScript", "JavaScript"); -// -// assertThat(resolved) -// .extracting(CompletionItem::getDetail) -// .containsExactly("TypeScript details", "JavaScript details"); -// -// assertThat(resolved) -// .extracting(CompletionItem::getDocumentation) -// .containsExactly("TypeScript docs", "JavaScript docs"); -// } - private void assertExpectedInitResult(InitializeResult initResult) { assertThat(initResult.getCapabilities().getCompletionProvider().getResolveProvider()).isFalse(); assertThat(initResult.getCapabilities().getTextDocumentSync()).isEqualTo(TextDocumentSyncKind.Incremental); diff --git a/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlEditorTest.java b/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlEditorTest.java deleted file mode 100644 index e002b38f5..000000000 --- a/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlEditorTest.java +++ /dev/null @@ -1,493 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016 Pivotal, Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.vscode.manifest.yaml; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.ide.vscode.concourse.ConcourseLanguageServer; -import org.springframework.ide.vscode.languageserver.testharness.Editor; -import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness; - -public class ManifestYamlEditorTest { - - LanguageServerHarness harness; - - @Before public void setup() throws Exception { - harness = new LanguageServerHarness(ConcourseLanguageServer::new); - harness.intialize(null); - } - - @Test public void testReconcileCatchesParseError() throws Exception { - - Editor editor = harness.newEditor( - "somemap: val\n"+ - "- sequence" - ); - editor.assertProblems( - "-|expected " - ); - } - - @Test public void reconcileRunsOnDocumentOpenAndChange() throws Exception { - LanguageServerHarness harness = new LanguageServerHarness(ConcourseLanguageServer::new); - harness.intialize(null); - - Editor editor = harness.newEditor( - "somemap: val\n"+ - "- sequence" - ); - - editor.assertProblems( - "-|expected " - ); - - editor.setText( - "- sequence\n" + - "zomemap: val" - ); - - editor.assertProblems( - "z|expected " - ); - } - - @Test - public void reconcileMisSpelledPropertyNames() throws Exception { - Editor editor; - - editor = harness.newEditor( - "memory: 1G\n" + - "aplications:\n" + - " - buildpack: zbuildpack\n" + - " domain: zdomain\n" + - " name: foo" - ); - editor.assertProblems("aplications|Unknown property"); - - //mispelled or not allowed at toplevel - editor = harness.newEditor( - "name: foo\n" + - "buildpeck: yahah\n" + - "memory: 1G\n" + - "memori: 1G\n" - ); - editor.assertProblems( - "name|Unknown property", - "buildpeck|Unknown property", - "memori|Unknown property" - ); - - //mispelled or not allowed as nested - editor = harness.newEditor( - "applications:\n" + - "- name: fine\n" + - " buildpeck: yahah\n" + - " memory: 1G\n" + - " memori: 1G\n" + - " applications: bad\n" - ); - editor.assertProblems( - "buildpeck|Unknown property", - "memori|Unknown property", - "applications|Unknown property" - ); - } - - @Test - public void reconcileStructuralProblems() throws Exception { - Editor editor; - - //forgot the 'applications:' heading - editor = harness.newEditor( - "- name: foo" - ); - editor.assertProblems( - "- name: foo|Expecting a 'Map' but found a 'Sequence'" - ); - - //forgot to make the '-' after applications - editor = harness.newEditor( - "applications:\n" + - " name: foo" - ); - editor.assertProblems( - "name: foo|Expecting a 'Sequence' but found a 'Map'" - ); - - //Using a 'composite' element where a scalar type is expected - editor = harness.newEditor( - "memory:\n"+ - "- bad sequence\n" + - "buildpack:\n" + - " bad: map\n" - ); - editor.assertProblems( - "- bad sequence|Expecting a 'Memory' but found a 'Sequence'", - "bad: map|Expecting a 'Buildpack' but found a 'Map'" - ); - } - - @Test - public void reconcileSimpleTypes() throws Exception { - Editor editor; - - //check for 'format' errors: - editor = harness.newEditor( - "applications:\n" + - "- name: foo\n" + - " instances: not a number\n" + - " no-route: notBool\n"+ - " memory: 1024\n" + - " disk_quota: 2048\n" + - " health-check-type: unhealthy" - ); - editor.assertProblems( - "not a number|Positive Integer", - "notBool|boolean", - "1024|Memory", - "2048|Memory", - "unhealthy|Health Check Type" - ); - - //check for 'range' errors: - editor = harness.newEditor( - "applications:\n" + - "- name: foo\n" + - " instances: -3\n" + - " memory: -1024M\n" + - " disk_quota: -2048M\n" - ); - editor.assertProblems( - "-3|Positive Integer", - "-1024M|Memory", - "-2048M|Memory" - ); - - //check that correct values are indeed accepted - editor = harness.newEditor( - "applications:\n" + - "- name: foo\n" + - " instances: 2\n" + - " no-route: true\n"+ - " memory: 1024M\n" + - " disk_quota: 2048MB\n" - ); - editor.assertProblems(/*none*/); - - //check that correct values are indeed accepted - editor = harness.newEditor( - "applications:\n" + - "- name: foo\n" + - " instances: 2\n" + - " no-route: false\n" + - " memory: 1024m\n" + - " disk_quota: 2048mb\n" - ); - editor.assertProblems(/*none*/); - - editor = harness.newEditor( - "applications:\n" + - "- name: foo\n" + - " instances: 2\n" + - " memory: 1G\n" + - " disk_quota: 2g\n" - ); - editor.assertProblems(/*none*/); - } - - @Test - public void noListIndent() throws Exception { - Editor editor; - editor = harness.newEditor("appl<*>"); - editor.assertCompletions( - "applications:\n"+ - "- <*>" - ); - } - - @Test - public void toplevelCompletions() throws Exception { - Editor editor; - editor = harness.newEditor("<*>"); - editor.assertCompletions( - "applications:\n"+ - "- <*>", - // --------------- - "buildpack: <*>", - // --------------- - "command: <*>", - // --------------- - "disk_quota: <*>", - // --------------- - "domain: <*>", - // --------------- - "domains:\n"+ - "- <*>", - // --------------- - "env:\n"+ - " <*>", - // --------------- - "health-check-type: <*>", - // --------------- -// "host: <*>", - // --------------- -// "hosts: \n"+ -// " - <*>", - // --------------- - "inherit: <*>", - // --------------- - "instances: <*>", - // --------------- - "memory: <*>", - // --------------- -// "name: <*>", - // --------------- - "no-hostname: <*>", - // --------------- - "no-route: <*>", - // --------------- - "path: <*>", - // --------------- - "random-route: <*>", - // --------------- - "services:\n"+ - "- <*>", - // --------------- - "stack: <*>", - // --------------- - "timeout: <*>" - ); - - editor = harness.newEditor("ranro<*>"); - editor.assertCompletions( - "random-route: <*>" - ); - } - - @Test - public void nestedCompletions() throws Exception { - Editor editor; - editor = harness.newEditor( - "applications:\n" + - "- <*>" - ); - editor.assertCompletions( - // --------------- - "applications:\n" + - "- buildpack: <*>", - // --------------- - "applications:\n" + - "- command: <*>", - // --------------- - "applications:\n" + - "- disk_quota: <*>", - // --------------- - "applications:\n" + - "- domain: <*>", - // --------------- - "applications:\n" + - "- domains:\n"+ - " - <*>", - // --------------- - "applications:\n" + - "- env:\n"+ - " <*>", - // --------------- - "applications:\n" + - "- health-check-type: <*>", - // --------------- - "applications:\n" + - "- host: <*>", - // --------------- - "applications:\n" + - "- hosts:\n"+ - " - <*>", - // --------------- - "applications:\n" + - "- instances: <*>", - // --------------- - "applications:\n" + - "- memory: <*>", - // --------------- - "applications:\n" + - "- name: <*>", - // --------------- - "applications:\n" + - "- no-hostname: <*>", - // --------------- - "applications:\n" + - "- no-route: <*>", - // --------------- - "applications:\n" + - "- path: <*>", - // --------------- - "applications:\n" + - "- random-route: <*>", - // --------------- - "applications:\n" + - "- services:\n"+ - " - <*>", - // --------------- - "applications:\n" + - "- stack: <*>", - // --------------- - "applications:\n" + - "- timeout: <*>" - ); - } - - @Test - public void completionDetailsAndDocs() throws Exception { - Editor editor = harness.newEditor( - "applications:\n" + - "- build<*>" - ); - editor.assertCompletionDetails("buildpack", "Buildpack", "If your application requires a custom buildpack"); - } - - @Test - public void valueCompletions() throws Exception { - assertCompletions("disk_quota: <*>", - "disk_quota: 1024M<*>", - "disk_quota: 256M<*>", - "disk_quota: 512M<*>" - ); - assertCompletions("memory: <*>", - "memory: 1024M<*>", - "memory: 256M<*>", - "memory: 512M<*>" - ); - assertCompletions("no-hostname: <*>", - "no-hostname: false<*>", - "no-hostname: true<*>" - ); - assertCompletions("no-route: <*>", - "no-route: false<*>", - "no-route: true<*>" - ); - assertCompletions("random-route: <*>", - "random-route: false<*>", - "random-route: true<*>" - ); - - assertCompletions("health-check-type: <*>", - "health-check-type: none<*>", - "health-check-type: port<*>" - ); - } - - @Test - public void hoverInfos() throws Exception { - Editor editor = harness.newEditor( - "memory: 1G\n" + - "#comment\n" + - "inherit: base-manifest.yml\n"+ - "applications:\n" + - "- buildpack: zbuildpack\n" + - " domain: zdomain\n" + - " name: foo\n" + - " command: java main.java\n" + - " disk_quota: 1024M\n" + - " domains:\n" + - " - pivotal.io\n" + - " - otherdomain.org\n" + - " env:\n" + - " RAILS_ENV: production\n" + - " RACK_ENV: production\n" + - " host: apppage\n" + - " hosts:\n" + - " - apppage2\n" + - " - appage3\n" + - " instances: 2\n" + - " no-hostname: true\n" + - " no-route: true\n" + - " path: somepath/app.jar\n" + - " random-route: true\n" + - " services:\n" + - " - instance_ABC\n" + - " - instance_XYZ\n" + - " stack: cflinuxfs2\n" + - " timeout: 80\n" + - " health-check-type: none\n" - ); - - editor.assertIsHoverRegion("memory"); - editor.assertIsHoverRegion("inherit"); - editor.assertIsHoverRegion("applications"); - editor.assertIsHoverRegion("buildpack"); - editor.assertIsHoverRegion("domain"); - editor.assertIsHoverRegion("name"); - editor.assertIsHoverRegion("command"); - editor.assertIsHoverRegion("disk_quota"); - editor.assertIsHoverRegion("domains"); - editor.assertIsHoverRegion("env"); - editor.assertIsHoverRegion("host"); - editor.assertIsHoverRegion("hosts"); - editor.assertIsHoverRegion("instances"); - editor.assertIsHoverRegion("no-hostname"); - editor.assertIsHoverRegion("no-route"); - editor.assertIsHoverRegion("path"); - editor.assertIsHoverRegion("random-route"); - editor.assertIsHoverRegion("services"); - editor.assertIsHoverRegion("stack"); - editor.assertIsHoverRegion("timeout"); - editor.assertIsHoverRegion("health-check-type"); - - editor.assertHoverContains("memory", "Use the `memory` attribute to specify the memory limit"); - editor.assertHoverContains("1G", "Use the `memory` attribute to specify the memory limit"); - editor.assertHoverContains("inherit", "For example, every child of a parent manifest called `base-manifest.yml` begins like this"); - editor.assertHoverContains("buildpack", "use the `buildpack` attribute to specify its URL or name"); - editor.assertHoverContains("name", "The `name` attribute is the only required attribute for an application in a manifest file"); - editor.assertHoverContains("command", "On the command line, use the `-c` option to specify the custom start command as the following example shows"); - editor.assertHoverContains("disk_quota", "Use the `disk_quota` attribute to allocate the disk space for your app instance"); - editor.assertHoverContains("domain", "You can use the `domain` attribute when you want your application to be served"); - editor.assertHoverContains("domains", "Use the `domains` attribute to provide multiple domains"); - editor.assertHoverContains("env", "The `env` block consists of a heading, then one or more environment variable/value pairs"); - editor.assertHoverContains("host", "Use the `host` attribute to provide a hostname, or subdomain, in the form of a string"); - editor.assertHoverContains("hosts", "Use the `hosts` attribute to provide multiple hostnames, or subdomains"); - editor.assertHoverContains("instances", "Use the `instances` attribute to specify the number of app instances that you want to start upon push"); - editor.assertHoverContains("no-hostname", "By default, if you do not provide a hostname, the URL for the app takes the form of `APP-NAME.DOMAIN`"); - editor.assertHoverContains("no-route", "You can use the `no-route` attribute with a value of `true` to prevent a route from being created for your application"); - editor.assertHoverContains("path", "You can use the `path` attribute to tell Cloud Foundry where to find your application"); - editor.assertHoverContains("random-route", "Use the `random-route` attribute to create a URL that includes the app name and random words"); - editor.assertHoverContains("services", "The `services` block consists of a heading, then one or more service instance names"); - editor.assertHoverContains("stack", "Use the `stack` attribute to specify which stack to deploy your application to."); - editor.assertHoverContains("timeout", "The `timeout` attribute defines the number of seconds Cloud Foundry allocates for starting your application"); - editor.assertHoverContains("health-check-type", "Use the `health-check-type` attribute to"); - } - - @Test - public void noHoverInfos() throws Exception { - Editor editor = harness.newEditor( - "#comment\n" + - "applications:\n" + - "- buildpack: zbuildpack\n" + - " name: foo\n" + - " domains:\n" + - " - pivotal.io\n" + - " - otherdomain.org\n" - - ); - editor.assertNoHover("comment"); - - // May fail in the future if hover support is added, but if hover support is added in the future, - // it is expected that these should start to fail, as right now they have no hover - editor.assertNoHover("pivotal.io"); - editor.assertNoHover("otherdomain.org"); - } - - ////////////////////////////////////////////////////////////////////////////// - - private void assertCompletions(String textBefore, String... textAfter) throws Exception { - Editor editor = harness.newEditor(textBefore); - editor.assertCompletions(textAfter); - } -} diff --git a/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/PipelineYamlEditorTest.java b/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/PipelineYamlEditorTest.java new file mode 100644 index 000000000..9183169fb --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/PipelineYamlEditorTest.java @@ -0,0 +1,258 @@ +/******************************************************************************* + * Copyright (c) 2016 Pivotal, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.manifest.yaml; + +import java.io.InputStream; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.ide.vscode.commons.util.IOUtil; +import org.springframework.ide.vscode.concourse.ConcourseLanguageServer; +import org.springframework.ide.vscode.languageserver.testharness.Editor; +import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness; + +public class PipelineYamlEditorTest { + + LanguageServerHarness harness; + + @Before public void setup() throws Exception { + harness = new LanguageServerHarness(ConcourseLanguageServer::new); + harness.intialize(null); + } + + @Test public void testReconcileCatchesParseError() throws Exception { + Editor editor = harness.newEditor( + "somemap: val\n"+ + "- sequence" + ); + editor.assertProblems( + "-|expected " + ); + } + + @Test public void reconcileRunsOnDocumentOpenAndChange() throws Exception { + LanguageServerHarness harness = new LanguageServerHarness(ConcourseLanguageServer::new); + harness.intialize(null); + + Editor editor = harness.newEditor( + "somemap: val\n"+ + "- sequence" + ); + + editor.assertProblems( + "-|expected " + ); + + editor.setText( + "- sequence\n" + + "zomemap: val" + ); + + editor.assertProblems( + "z|expected " + ); + } + + @Test + public void reconcileMisSpelledPropertyNames() throws Exception { + Editor editor; + + editor = harness.newEditor( + "resorces:\n" + + "- name: git\n" + + " type: git\n" + ); + editor.assertProblems("resorces|Unknown property"); + } + + @Test + public void reconcileAcceptsSensiblePipelineFile() throws Exception { + Editor editor; + + editor = harness.newEditor( + getClasspathResourceText("workspace/pipeline.yml") + ); + editor.assertProblems(/*NONE*/);; + } + + private String getClasspathResourceText(String resourceName) throws Exception { + InputStream stream = PipelineYamlEditorTest.class.getClassLoader().getResourceAsStream(resourceName); + return IOUtil.toString(stream); + } + + @Test + public void reconcileStructuralProblems() throws Exception { + Editor editor; + + //resources should be a sequence not a map, even if there's only one entry + editor = harness.newEditor( + "resources:\n" + + " name: git\n" + + " type: git\n" + ); + editor.assertProblems( + "name: git\n type: git|Expecting a 'Sequence' but found a 'Map'" + ); + + //TODO: Add more test cases for structural problem? + } + + @Test + public void reconcileSimpleTypes() throws Exception { + Editor editor; + + //check for 'format' errors: + editor = harness.newEditor( + "jobs:\n" + + "- name: foo\n" + + " serial: boohoo\n" + + " max_in_flight: 0\n" + + " plan:\n" + + " - get: git\n" + + " trigger: yohoho" + ); + editor.assertProblems( + "boohoo|boolean", + "0|Positive Integer", + "yohoho|boolean" + ); + + //check that correct values are indeed accepted + editor = harness.newEditor( + "jobs:\n" + + "- name: foo\n" + + " serial: true\n" + + " max_in_flight: 2\n" + + " plan:\n" + + " - get: git\n" + + " trigger: true" + ); + editor.assertProblems(/*none*/); + + } + + @Test + public void noListIndent() throws Exception { + Editor editor; + editor = harness.newEditor("jo<*>"); + editor.assertCompletions( + "jobs:\n"+ + "- <*>" + ); + } + + @Test + public void toplevelCompletions() throws Exception { + Editor editor; + editor = harness.newEditor("<*>"); + editor.assertCompletions( + "resources:\n"+ + "- <*>", + // --------------- + "resource-types:\n" + + "- <*>", + // --------------- + "jobs:\n" + + "- <*>" + ); + + editor = harness.newEditor("ranro<*>"); + editor.assertCompletions( + "random-route: <*>" + ); + } + + @Test + public void completionDetailsAndDocs() throws Exception { + Editor editor = harness.newEditor( + "applications:\n" + + "- build<*>" + ); + editor.assertCompletionDetails("buildpack", "Buildpack", "If your application requires a custom buildpack"); + } + + @Test + public void valueCompletions() throws Exception { + assertCompletions( + "resources:\n" + + "- type: <*>" + , //=> + "resources:\n" + + "- type: archive<*>", + "resources:\n" + + "- type: docker-image<*>", + "resources:\n" + + "- type: git<*>", + "resources:\n" + + "- type: s3<*>", + "resources:\n" + + "- type: semver<*>", + "resources:\n" + + "- type: time<*>" + ); + assertCompletions( + "jobs:\n" + + "- name: foo\n" + + " serial: <*>" + , // => + "jobs:\n" + + "- name: foo\n" + + " serial: false<*>" + , // -- + "jobs:\n" + + "- name: foo\n" + + " serial: true<*>" + ); + } + + @Test + public void topLevelHoverInfos() throws Exception { + Editor editor = harness.newEditor( + "resource_types:\n" + + "- name: s3-multi\n" + + " type: docker-image\n" + + " source:\n" + + " repository: kdvolder/s3-resource-simple\n" + + "resources:\n" + + "- name: docker-git\n" + + " type: git\n" + + " source:\n" + + " uri: git@github.com:spring-projects/sts4.git\n" + + " branch: {{branch}}\n" + + " username: kdvolder\n" + + " private_key: {{rsa_id}}\n" + + " paths:\n" + + " - concourse/docker\n" + + "jobs:\n" + + "- name: build-docker-image\n" + + " serial: true\n" + + " plan:\n" + + " - get: docker-git\n" + + " trigger: true\n" + + " - put: docker-image\n" + + " params:\n" + + " build: docker-git/concourse/docker\n" + + " get_params: \n" + + " skip_download: true\n" + ); + + editor.assertHoverContains("resource_types", "each pipeline can configure its own custom types by specifying `resource_types` at the top level."); + editor.assertHoverContains("resources", "A resource is any entity that can be checked for new versions"); + editor.assertHoverContains("jobs", "At a high level, a job describes some actions to perform"); + } + + ////////////////////////////////////////////////////////////////////////////// + + private void assertCompletions(String textBefore, String... textAfter) throws Exception { + Editor editor = harness.newEditor(textBefore); + editor.assertCompletions(textAfter); + } +} diff --git a/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/ManifestYmlSchemaTest.java b/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/PipelineYmlSchemaTest.java similarity index 87% rename from vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/ManifestYmlSchemaTest.java rename to vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/PipelineYmlSchemaTest.java index f1aa4d507..a39093695 100644 --- a/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/ManifestYmlSchemaTest.java +++ b/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/manifest/yaml/PipelineYmlSchemaTest.java @@ -13,11 +13,12 @@ package org.springframework.ide.vscode.manifest.yaml; import static org.junit.Assert.fail; import org.junit.Test; +import org.springframework.ide.vscode.concourse.PipelineYmlSchema; /** * @author Kris De Volder */ -public class ManifestYmlSchemaTest { +public class PipelineYmlSchemaTest { @Test public void shouldMakeSomeTests() { @@ -48,31 +49,14 @@ public class ManifestYmlSchemaTest { // "timeout" // }; // -// private static final String[] TOPLEVEL_PROP_NAMES = { -// "applications", -// "buildpack", -// "command", -// "disk_quota", -// "domain", -// "domains", -// "env", -// "health-check-type", -//// "host", -//// "hosts", -// "inherit", -// "instances", -// "memory", -//// "name", -// "no-hostname", -// "no-route", -// "path", -// "random-route", -// "services", -// "stack", -// "timeout" -// }; -// -// PipelineYmlSchema schema = new PipelineYmlSchema(null); + private static final String[] TOPLEVEL_PROP_NAMES = { + "resources", + "jobs", + "resource-types" + //groups + }; + + PipelineYmlSchema schema = new PipelineYmlSchema(); // // @Test // public void toplevelProperties() throws Exception { diff --git a/vscode-extensions/vscode-concourse/test/examples/another-pipeline.yml b/vscode-extensions/vscode-concourse/src/test/resources/workspace/another-pipeline.yml similarity index 100% rename from vscode-extensions/vscode-concourse/test/examples/another-pipeline.yml rename to vscode-extensions/vscode-concourse/src/test/resources/workspace/another-pipeline.yml diff --git a/vscode-extensions/vscode-concourse/src/test/resources/workspace/manifest.yml b/vscode-extensions/vscode-concourse/src/test/resources/workspace/manifest.yml deleted file mode 100644 index 7160866ac..000000000 --- a/vscode-extensions/vscode-concourse/src/test/resources/workspace/manifest.yml +++ /dev/null @@ -1,5 +0,0 @@ -#Comment -applications: -- name: foo - buildpack: something - \ No newline at end of file diff --git a/vscode-extensions/vscode-concourse/test/examples/pipeline.yml b/vscode-extensions/vscode-concourse/src/test/resources/workspace/pipeline.yml similarity index 100% rename from vscode-extensions/vscode-concourse/test/examples/pipeline.yml rename to vscode-extensions/vscode-concourse/src/test/resources/workspace/pipeline.yml diff --git a/vscode-extensions/vscode-concourse/test/examples/tasks/build-stuff.yml b/vscode-extensions/vscode-concourse/src/test/resources/workspace/tasks/build-stuff.yml similarity index 100% rename from vscode-extensions/vscode-concourse/test/examples/tasks/build-stuff.yml rename to vscode-extensions/vscode-concourse/src/test/resources/workspace/tasks/build-stuff.yml diff --git a/vscode-extensions/vscode-concourse/test/examples/tasks/build-vscode-extensions.sh b/vscode-extensions/vscode-concourse/src/test/resources/workspace/tasks/build-vscode-extensions.sh similarity index 100% rename from vscode-extensions/vscode-concourse/test/examples/tasks/build-vscode-extensions.sh rename to vscode-extensions/vscode-concourse/src/test/resources/workspace/tasks/build-vscode-extensions.sh diff --git a/vscode-extensions/vscode-concourse/test/examples/tasks/build-vscode-extensions.yml b/vscode-extensions/vscode-concourse/src/test/resources/workspace/tasks/build-vscode-extensions.yml similarity index 100% rename from vscode-extensions/vscode-concourse/test/examples/tasks/build-vscode-extensions.yml rename to vscode-extensions/vscode-concourse/src/test/resources/workspace/tasks/build-vscode-extensions.yml diff --git a/vscode-extensions/vscode-concourse/test/examples/tasks/build-website.sh b/vscode-extensions/vscode-concourse/src/test/resources/workspace/tasks/build-website.sh similarity index 100% rename from vscode-extensions/vscode-concourse/test/examples/tasks/build-website.sh rename to vscode-extensions/vscode-concourse/src/test/resources/workspace/tasks/build-website.sh diff --git a/vscode-extensions/vscode-concourse/test/examples/tasks/build-website.yml b/vscode-extensions/vscode-concourse/src/test/resources/workspace/tasks/build-website.yml similarity index 100% rename from vscode-extensions/vscode-concourse/test/examples/tasks/build-website.yml rename to vscode-extensions/vscode-concourse/src/test/resources/workspace/tasks/build-website.yml diff --git a/vscode-extensions/vscode-concourse/test/examples/tasks/test-stuff.yml b/vscode-extensions/vscode-concourse/src/test/resources/workspace/tasks/test-stuff.yml similarity index 100% rename from vscode-extensions/vscode-concourse/test/examples/tasks/test-stuff.yml rename to vscode-extensions/vscode-concourse/src/test/resources/workspace/tasks/test-stuff.yml diff --git a/vscode-extensions/vscode-concourse/test/examples/destroy-pipeline.sh b/vscode-extensions/vscode-concourse/test/examples/destroy-pipeline.sh deleted file mode 100755 index 09a9e09db..000000000 --- a/vscode-extensions/vscode-concourse/test/examples/destroy-pipeline.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -branch=`git rev-parse --abbrev-ref HEAD` -fly -t tools destroy-pipeline -p sts4-${branch} - diff --git a/vscode-extensions/vscode-concourse/test/examples/docker/Dockerfile b/vscode-extensions/vscode-concourse/test/examples/docker/Dockerfile deleted file mode 100644 index 02f4a5a1f..000000000 --- a/vscode-extensions/vscode-concourse/test/examples/docker/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM ubuntu:16.04 - -ADD npmrc /root/.npmrc - -RUN apt-get update && apt-get install -y \ - build-essential \ - gettext-base \ - git \ - jq \ - openjdk-8-jdk \ - maven \ - curl - -RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - \ - && apt-get install -y nodejs - -CMD /bin/bash diff --git a/vscode-extensions/vscode-concourse/test/examples/docker/npmrc b/vscode-extensions/vscode-concourse/test/examples/docker/npmrc deleted file mode 100644 index 3364a1762..000000000 --- a/vscode-extensions/vscode-concourse/test/examples/docker/npmrc +++ /dev/null @@ -1 +0,0 @@ -unsafe-perm=true \ No newline at end of file diff --git a/vscode-extensions/vscode-concourse/test/examples/set-pipeline.sh b/vscode-extensions/vscode-concourse/test/examples/set-pipeline.sh deleted file mode 100755 index 2fcdaabc5..000000000 --- a/vscode-extensions/vscode-concourse/test/examples/set-pipeline.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -branch=`git rev-parse --abbrev-ref HEAD` -fly -t tools set-pipeline --var "branch=${branch}" --load-vars-from ${HOME}/.sts4-concourse-credentials.yml -p sts4-${branch} -c pipeline.yml