Some cleanups

- Failing test cases
- Genericise CludConfigProvider
This commit is contained in:
Kris De Volder
2017-07-19 11:38:26 -07:00
parent 35a558be37
commit 506ffe8f03
9 changed files with 82 additions and 38 deletions

View File

@@ -14,7 +14,8 @@ import java.util.Collection;
import java.util.Map;
import java.util.UUID;
import org.springframework.ide.vscode.bosh.cloudconfig.CloudConfigProvider;
import org.springframework.ide.vscode.bosh.cloudconfig.CloudConfigModel;
import org.springframework.ide.vscode.bosh.cloudconfig.DynamicModelProvider;
import org.springframework.ide.vscode.commons.util.Assert;
import org.springframework.ide.vscode.commons.util.Renderable;
import org.springframework.ide.vscode.commons.util.Renderables;
@@ -78,9 +79,9 @@ public class BoshDeploymentManifestSchema implements YamlSchema {
private YType t_release_name_ref;
private YType t_var_name_def;
private final ASTTypeCache astTypes;
private CloudConfigProvider cloudConfigProvider;
private DynamicModelProvider<CloudConfigModel> cloudConfigProvider;
public BoshDeploymentManifestSchema(ASTTypeCache astTypes, CloudConfigProvider cloudConfigProvider) {
public BoshDeploymentManifestSchema(ASTTypeCache astTypes, DynamicModelProvider<CloudConfigModel> cloudConfigProvider) {
this.astTypes = astTypes;
this.cloudConfigProvider = cloudConfigProvider;
TYPE_UTIL = f.TYPE_UTIL;
@@ -146,8 +147,7 @@ public class BoshDeploymentManifestSchema implements YamlSchema {
YAtomicType t_vm_extension = f.yatomic("VMExtension"); //TODO: resolve dynamically from 'cloud config' ? https://www.pivotaltracker.com/story/show/148703877
t_vm_extension.parseWith(ValueParsers.NE_STRING);
YAtomicType t_vm_type = f.yenumFromDynamicValues("VMType", (dc) -> cloudConfigProvider.getCloudConfig(dc).getVMTypes());
t_vm_type.parseWith(ValueParsers.NE_STRING);
YAtomicType t_vm_type = f.yenumFromDynamicValues("VMType", (dc) -> cloudConfigProvider.getModel(dc).getVMTypes());
YAtomicType t_az = f.yatomic("AvailabilityZone"); //TODO: resolve dynamically from 'cloud config': https://www.pivotaltracker.com/story/show/148704481
t_az.parseWith(ValueParsers.NE_STRING);

View File

@@ -10,7 +10,8 @@
*******************************************************************************/
package org.springframework.ide.vscode.bosh;
import org.springframework.ide.vscode.bosh.cloudconfig.CloudConfigProvider;
import org.springframework.ide.vscode.bosh.cloudconfig.CloudConfigModel;
import org.springframework.ide.vscode.bosh.cloudconfig.DynamicModelProvider;
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter;
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter.LazyCompletionResolver;
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfoProvider;
@@ -41,7 +42,7 @@ public class BoshLanguageServer extends SimpleLanguageServer {
private final LazyCompletionResolver completionResolver = new LazyCompletionResolver(); //Set to null to disable lazy resolving
private final VscodeCompletionEngineAdapter completionEngine;
public BoshLanguageServer(CloudConfigProvider cloudConfigProvider) {
public BoshLanguageServer(DynamicModelProvider<CloudConfigModel> cloudConfigProvider) {
super("vscode-bosh");
YamlASTProvider parser = new YamlParser(yaml);
SimpleTextDocumentService documents = getTextDocumentService();

View File

@@ -41,11 +41,13 @@ import com.fasterxml.jackson.databind.ObjectMapper;
*
* @author Kris De Volder
*/
public class BoshCommandCloudConfigProvider implements CloudConfigProvider {
public class BoshCommandCloudConfigProvider implements DynamicModelProvider<CloudConfigModel> {
ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
final YamlParser yamlParser;
private Duration CMD_TIMEOUT = Duration.ofSeconds(10);
public BoshCommandCloudConfigProvider() {
Representer representer = new Representer();
representer.getPropertyUtils().setSkipMissingProperties(true);
@@ -75,7 +77,7 @@ public class BoshCommandCloudConfigProvider implements CloudConfigProvider {
.thenValAt("name");
@Override
public CloudConfigModel getCloudConfig(DynamicSchemaContext dc) throws Exception {
public CloudConfigModel getModel(DynamicSchemaContext dc) throws Exception {
String out = executeBoshCloudConfigCommand();
CloudConfigResponse response = mapper.readValue(out, CloudConfigResponse.class);
String[] blocks = response.getBlocks();
@@ -99,9 +101,18 @@ public class BoshCommandCloudConfigProvider implements CloudConfigProvider {
};
}
/**
* Configure how long we wait for the command to fetch cloud config before
* raising timeout exception. (The command may block for long amounts of time
* of the director is unreachable on the network).
*/
public void setCommandTimeout(Duration duration) {
this.CMD_TIMEOUT = duration;
}
protected String executeBoshCloudConfigCommand() throws Exception {
ExternalCommand command = new ExternalCommand("bosh", "cloud-config", "--json");
ExternalProcess process = new ExternalProcess(new File(".").getAbsoluteFile(), command, true, Duration.ofSeconds(30));
ExternalProcess process = new ExternalProcess(new File(".").getAbsoluteFile(), command, true, CMD_TIMEOUT);
System.out.println("executeBoshCloudConfigCommand: "+process);
String out = process.getOut();
return out;

View File

@@ -5,8 +5,6 @@ import org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext;
/**
* Responsible for somehow obtaining {@link CloudConfigModel} relative to a {@link DynamicSchemaContext}
*/
public interface CloudConfigProvider {
CloudConfigModel getCloudConfig(DynamicSchemaContext dc) throws Exception;
public interface DynamicModelProvider<T> {
T getModel(DynamicSchemaContext dc) throws Exception;
}

View File

@@ -16,25 +16,14 @@ import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.ide.vscode.bosh.cloudconfig.BoshCommandCloudConfigProvider;
import org.springframework.ide.vscode.bosh.cloudconfig.CloudConfigModel;
import org.springframework.ide.vscode.commons.util.IOUtil;
import org.springframework.ide.vscode.bosh.mocks.MockCloudConfigProvider;
import org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext;
import com.google.common.collect.ImmutableMultiset;
public class BoshCommandCloudConfigProviderTest {
private static final String MOCK_DATA_RSRC = "/cmd-out/cloud-config.json";
public static final BoshCommandCloudConfigProvider mockProvider = new BoshCommandCloudConfigProvider() {
/**
* Override with a 'fake' which just returns some mock data. That way we can unit-test
* without requiring a real bosh setup.
*/
@Override
protected String executeBoshCloudConfigCommand() throws Exception {
return IOUtil.toString(BoshCommandCloudConfigProviderTest.class.getResourceAsStream(MOCK_DATA_RSRC));
};
};
public final MockCloudConfigProvider mockProvider = new MockCloudConfigProvider();
// For local testing only... in CI builds we don't have the means to use a real bosh director and cli.
// private BoshCommandCloudConfigProvider realProvider = new BoshCommandCloudConfigProvider();
@@ -42,7 +31,7 @@ public class BoshCommandCloudConfigProviderTest {
@Test public void getVMTypes() throws Exception {
BoshCommandCloudConfigProvider provider = mockProvider;
DynamicSchemaContext dc = Mockito.mock(DynamicSchemaContext.class);
CloudConfigModel cloudConfig = provider.getCloudConfig(dc);
CloudConfigModel cloudConfig = provider.getModel(dc);
assertEquals(ImmutableMultiset.of("default", "large"), cloudConfig.getVMTypes());
}

View File

@@ -12,8 +12,11 @@ package org.springframework.ide.vscode.bosh;
import static org.springframework.ide.vscode.languageserver.testharness.Editor.PLAIN_COMPLETION;
import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
import org.springframework.ide.vscode.bosh.mocks.MockCloudConfigProvider;
import org.springframework.ide.vscode.commons.util.text.LanguageId;
import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaProblems;
import org.springframework.ide.vscode.languageserver.testharness.Editor;
@@ -23,9 +26,11 @@ public class BoshEditorTest {
LanguageServerHarness harness;
private MockCloudConfigProvider cloudConfigProvider = new MockCloudConfigProvider();
@Before public void setup() throws Exception {
harness = new LanguageServerHarness(() -> {
return new BoshLanguageServer(BoshCommandCloudConfigProviderTest.mockProvider)
return new BoshLanguageServer(cloudConfigProvider)
.setMaxCompletions(100);
},
LanguageId.BOSH_DEPLOYMENT
@@ -58,7 +63,7 @@ public class BoshEditorTest {
" release: redis\n" +
" properties:\n" +
" port: 3606\n" +
" vm_type: medium\n" +
" vm_type: large\n" +
" vm_extensions: [public-lbs]\n" +
" stemcell: default\n" +
" persistent_disk_type: medium\n" +
@@ -71,9 +76,9 @@ public class BoshEditorTest {
" - name: redis-server\n" +
" release: redis\n" +
" properties: {}\n" +
" vm_type: medium\n" +
" vm_type: large\n" +
" stemcell: default\n" +
" persistent_disk_type: medium\n" +
" persistent_disk_type: large\n" +
" networks:\n" +
" - name: default\n" +
"variables:\n" +
@@ -116,6 +121,9 @@ public class BoshEditorTest {
//@Ignore //For now... because not passing yet.
@Test public void reconcileCfManifest() throws Exception {
Editor editor = harness.newEditorFromClasspath("/workspace/cf-deployment-manifest.yml");
cloudConfigProvider.readWith(() -> {
throw new IOException("Couldn't contact the director");
});
editor.assertProblems(/*NONE*/);
}

View File

@@ -8,7 +8,6 @@
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.bosh;
import static org.assertj.core.api.Assertions.assertThat;
@@ -20,7 +19,7 @@ import java.nio.file.Paths;
import org.eclipse.lsp4j.InitializeResult;
import org.eclipse.lsp4j.TextDocumentSyncKind;
import org.junit.Test;
import org.springframework.ide.vscode.bosh.BoshLanguageServer;
import org.springframework.ide.vscode.bosh.mocks.MockCloudConfigProvider;
import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness;
public class BoshLanguageServerTest {
@@ -32,7 +31,7 @@ public class BoshLanguageServerTest {
@Test
public void createAndInitializeServerWithWorkspace() throws Exception {
LanguageServerHarness harness = new LanguageServerHarness(() ->
new BoshLanguageServer(BoshCommandCloudConfigProviderTest.mockProvider)
new BoshLanguageServer(new MockCloudConfigProvider())
);
File workspaceRoot = getTestResource("/workspace/");
assertExpectedInitResult(harness.intialize(workspaceRoot));
@@ -42,7 +41,7 @@ public class BoshLanguageServerTest {
public void createAndInitializeServerWithoutWorkspace() throws Exception {
File workspaceRoot = null;
LanguageServerHarness harness = new LanguageServerHarness(() ->
new BoshLanguageServer(BoshCommandCloudConfigProviderTest.mockProvider)
new BoshLanguageServer(new MockCloudConfigProvider())
);
assertExpectedInitResult(harness.intialize(workspaceRoot));
}

View File

@@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright (c) 2017 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.bosh.mocks;
import java.util.concurrent.Callable;
import org.springframework.ide.vscode.bosh.BoshCommandCloudConfigProviderTest;
import org.springframework.ide.vscode.bosh.cloudconfig.BoshCommandCloudConfigProvider;
import org.springframework.ide.vscode.commons.util.IOUtil;
public final class MockCloudConfigProvider extends BoshCommandCloudConfigProvider {
static final String MOCK_DATA_RSRC = "/cmd-out/cloud-config.json";
private Callable<String> cloudConfigReader = () -> IOUtil.toString(BoshCommandCloudConfigProviderTest.class.getResourceAsStream(MOCK_DATA_RSRC));
/**
* Override with a 'fake' which just returns some mock data. That way we can unit-test
* without requiring a real bosh setup.
*/
@Override
protected String executeBoshCloudConfigCommand() throws Exception {
return cloudConfigReader.call();
}
public MockCloudConfigProvider readWith(Callable<String> reader) {
this.cloudConfigReader = reader;
return this;
}
}

View File

@@ -216,7 +216,7 @@ public class YTypeAssistContext extends AbstractYamlAssistContext {
}
for (YValueHint value : values) {
double score = FuzzyMatcher.matchScore(query, value.getValue());
if (score!=0 && !value.equals(query)) {
if (score!=0 && value!=null && !query.equals(value.getValue())) {
int queryStart = offset-query.length();
DocumentEdits edits = new DocumentEdits(doc.getDocument());
edits.delete(queryStart, offset);
@@ -358,7 +358,7 @@ public class YTypeAssistContext extends AbstractYamlAssistContext {
}
return null;
}
protected Collection<ICompletionProposal> getDashedCompletions(YamlDocument doc, SNode current, int offset) {
try {
YamlAssistContext relaxed = relaxForDashes();