-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Test against golden master testcases.yml (#29)
[RFC 004](palantir/conjure#35) defines some common test cases to prove that all languages conform to a common wire spec. This PR loads up the test-cases.json file and a known-good verification-server (published by the [palantir/conjure-verification](https://github.palantir.build/foundry/conjure-verification) repo) and runs the tests.
- Loading branch information
Showing
11 changed files
with
670 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/* | ||
* (c) Copyright 2018 Palantir Technologies Inc. All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import static org.apache.tools.ant.taskdefs.condition.Os.* | ||
|
||
ext { | ||
osClassifier = isFamily(FAMILY_MAC) ? "osx" : "linux" | ||
} | ||
|
||
// We locally-codegen verification-api.conjure.json into these source-sets | ||
sourceSets { | ||
generatedObjects | ||
generatedJersey | ||
} | ||
|
||
idea { | ||
module { | ||
generatedSourceDirs += sourceSets.generatedObjects.java.srcDirs | ||
generatedSourceDirs += sourceSets.generatedJersey.java.srcDirs | ||
scopes.COMPILE.plus += [configurations.generatedObjectsCompile, configurations.generatedJerseyCompile] | ||
} | ||
} | ||
|
||
configurations { | ||
testCases | ||
verificationApi | ||
verificationServer | ||
} | ||
|
||
dependencies { | ||
testCases 'com.palantir.conjure.verification:test-cases' | ||
verificationApi 'com.palantir.conjure.verification:verification-api' | ||
verificationServer "com.palantir.conjure.verification:verification-server::${osClassifier}@tgz" | ||
|
||
generatedObjectsCompile project(':conjure-java-core') | ||
generatedObjectsCompile project(':conjure-lib') | ||
|
||
generatedJerseyCompile project(':conjure-java-core') | ||
generatedJerseyCompile project(':conjure-lib') | ||
generatedJerseyCompile sourceSets.generatedObjects.output | ||
|
||
testCompile project(':conjure-java-core') | ||
testCompile 'junit:junit' | ||
testCompile 'org.assertj:assertj-core' | ||
testCompile 'org.mockito:mockito-core' | ||
testCompile 'com.palantir.remoting3:jaxrs-clients' | ||
testCompile 'io.dropwizard:dropwizard-testing' | ||
testCompile sourceSets.generatedObjects.output | ||
testCompile sourceSets.generatedJersey.output | ||
|
||
processor 'org.immutables:value' | ||
} | ||
|
||
tasks.compileTestJava { | ||
options.compilerArgs += ['-Xep:Slf4jLogsafeArgs:OFF'] | ||
} | ||
|
||
task unpackVerificationServer(type: Sync) { | ||
from { tarTree(configurations.verificationServer.singleFile) } | ||
into "${buildDir}/verification-server" | ||
rename { "server" } | ||
} | ||
|
||
task copyTestCases(type: Sync) { | ||
from configurations.testCases | ||
into "$buildDir/test-cases" | ||
rename { "test-cases.json" } | ||
} | ||
|
||
task conjureJavaObjects(type: JavaExec) { | ||
main = "com.palantir.conjure.java.cli.ConjureJavaCli" | ||
classpath = project(':conjure-java').sourceSets.main.runtimeClasspath | ||
args 'generate', "${-> configurations.verificationApi.singleFile}", 'src/generatedObjects/java', '--objects' | ||
|
||
inputs.file "${-> configurations.verificationApi.singleFile}" | ||
outputs.files "src/generatedObjects/java" | ||
doFirst { delete "src/generatedObjects/java/*" } | ||
} | ||
|
||
task conjureJavaJersey(type: JavaExec) { | ||
main = "com.palantir.conjure.java.cli.ConjureJavaCli" | ||
classpath = project(':conjure-java').sourceSets.main.runtimeClasspath | ||
args 'generate', "${-> configurations.verificationApi.singleFile}", 'src/generatedJersey/java', '--jersey' | ||
|
||
inputs.file "${-> configurations.verificationApi.singleFile}" | ||
outputs.files "src/generatedJersey/java" | ||
doFirst { delete "src/generatedJersey/java/*" } | ||
} | ||
|
||
compileGeneratedObjectsJava.dependsOn conjureJavaObjects | ||
compileGeneratedObjectsJava.dependsOn conjureJavaJersey | ||
|
||
tasks.idea.dependsOn conjureJavaObjects, conjureJavaJersey, unpackVerificationServer, copyTestCases | ||
test.dependsOn unpackVerificationServer, copyTestCases | ||
|
||
checkstyleGeneratedObjects.enabled = false | ||
checkstyleGeneratedJersey.enabled = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.java |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.java |
113 changes: 113 additions & 0 deletions
113
...java-verifier/src/test/java/com/palantir/conjure/java/compliance/AutoDeserializeTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
/* | ||
* (c) Copyright 2018 Palantir Technologies Inc. All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.palantir.conjure.java.compliance; | ||
|
||
import com.palantir.conjure.verification.AutoDeserializeConfirmService; | ||
import com.palantir.conjure.verification.AutoDeserializeService; | ||
import com.palantir.conjure.verification.EndpointName; | ||
import com.palantir.remoting.api.errors.RemoteException; | ||
import java.io.IOException; | ||
import java.lang.reflect.Method; | ||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.List; | ||
import java.util.stream.IntStream; | ||
import org.assertj.core.api.Assertions; | ||
import org.junit.Assume; | ||
import org.junit.ClassRule; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.junit.runners.Parameterized; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
@RunWith(Parameterized.class) | ||
public class AutoDeserializeTest { | ||
|
||
@ClassRule | ||
public static final VerificationServerRule server = new VerificationServerRule(); | ||
|
||
private static final Logger log = LoggerFactory.getLogger(AutoDeserializeTest.class); | ||
private static final AutoDeserializeService testService = VerificationClients.autoDeserializeService(server); | ||
private static final AutoDeserializeConfirmService confirmService = VerificationClients.confirmService(server); | ||
|
||
@Parameterized.Parameter(0) | ||
public EndpointName endpointName; | ||
|
||
@Parameterized.Parameter(1) | ||
public int index; | ||
|
||
@Parameterized.Parameter(2) | ||
public boolean shouldSucceed; | ||
|
||
@Parameterized.Parameter(3) | ||
public String jsonString; | ||
|
||
@Parameterized.Parameters(name = "{0}({3}) -> should succeed {2}") | ||
public static Collection<Object[]> data() throws IOException { | ||
|
||
List<Object[]> objects = new ArrayList<>(); | ||
Cases.TEST_CASES.getAutoDeserialize().forEach((endpointName, positiveAndNegativeTestCases) -> { | ||
int positiveSize = positiveAndNegativeTestCases.getPositive().size(); | ||
int negativeSize = positiveAndNegativeTestCases.getNegative().size(); | ||
|
||
IntStream.range(0, positiveSize).forEach(i -> objects.add(new Object[] { | ||
endpointName, i, true, | ||
positiveAndNegativeTestCases.getPositive().get(i)})); | ||
|
||
IntStream.range(0, negativeSize).forEach(i -> objects.add(new Object[] { | ||
endpointName, positiveSize + i, false, | ||
positiveAndNegativeTestCases.getNegative().get(i)})); | ||
}); | ||
return objects; | ||
} | ||
|
||
@Test | ||
public void runTestCase() throws Exception { | ||
Assume.assumeFalse(Cases.shouldIgnore(endpointName, jsonString)); | ||
|
||
Method method = testService.getClass().getMethod(endpointName.get(), int.class); | ||
System.out.println(String.format("Invoking %s(%s), expected %s", | ||
endpointName, | ||
jsonString, | ||
shouldSucceed ? "success" : "failure")); | ||
|
||
if (shouldSucceed) { | ||
expectSuccess(method); | ||
} else { | ||
expectFailure(method); | ||
} | ||
} | ||
|
||
private void expectSuccess(Method method) throws Exception { | ||
try { | ||
Object resultFromServer = method.invoke(testService, index); | ||
log.info("Received result for endpoint {} and index {}: {}", endpointName, index, resultFromServer); | ||
confirmService.confirm(endpointName.get(), index, resultFromServer); | ||
} catch (RemoteException e) { | ||
log.error("Caught exception with params: {}", e.getError().parameters()); | ||
throw e; | ||
} | ||
} | ||
|
||
private void expectFailure(Method method) { | ||
Assertions.assertThatExceptionOfType(Exception.class).isThrownBy(() -> { | ||
Object result = method.invoke(testService, index); | ||
log.error("Result should have caused an exception but deserialized to: {}", result); | ||
}); | ||
} | ||
} |
78 changes: 78 additions & 0 deletions
78
conjure-java-verifier/src/test/java/com/palantir/conjure/java/compliance/Cases.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* | ||
* (c) Copyright 2018 Palantir Technologies Inc. All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.palantir.conjure.java.compliance; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; | ||
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; | ||
import com.palantir.conjure.verification.ClientTestCases; | ||
import com.palantir.conjure.verification.EndpointName; | ||
import com.palantir.conjure.verification.IgnoredClientTestCases; | ||
import com.palantir.conjure.verification.IgnoredTestCases; | ||
import java.io.File; | ||
import java.io.IOException; | ||
import java.util.Set; | ||
import javax.annotation.Nullable; | ||
|
||
public final class Cases { | ||
|
||
public static final ClientTestCases TEST_CASES = deserializeTestCases( | ||
new File("build/test-cases/test-cases.json")); | ||
private static final IgnoredClientTestCases IGNORED_TEST_CASES = deserializeIgnoredClientTestCases( | ||
new File("src/test/resources/ignored-test-cases.yml")); | ||
|
||
private Cases() {} | ||
|
||
private static ClientTestCases deserializeTestCases(File file) { | ||
try { | ||
return new ObjectMapper() | ||
.registerModule(new Jdk8Module()) | ||
.readValue(file, com.palantir.conjure.verification.TestCases.class).getClient(); | ||
} catch (IOException e) { | ||
throw new RuntimeException( | ||
String.format("Unable to read %s, you may need to run ./gradlew copyTestCases", file), | ||
e); | ||
} | ||
} | ||
|
||
private static IgnoredClientTestCases deserializeIgnoredClientTestCases(File file) { | ||
try { | ||
return new ObjectMapper(new YAMLFactory()) | ||
.registerModule(new Jdk8Module()) | ||
.readValue(file, IgnoredTestCases.class).getClient(); | ||
} catch (IOException e) { | ||
throw new RuntimeException( | ||
String.format("Unable to read %s", file), | ||
e); | ||
} | ||
} | ||
|
||
public static boolean shouldIgnore(EndpointName endpointName, String json) { | ||
return setContains(IGNORED_TEST_CASES.getAutoDeserialize().get(endpointName), json) | ||
|| setContains(IGNORED_TEST_CASES.getSingleHeaderService().get(endpointName), json) | ||
|| setContains(IGNORED_TEST_CASES.getSinglePathParamService().get(endpointName), json) | ||
|| setContains(IGNORED_TEST_CASES.getSingleQueryParamService().get(endpointName), json); | ||
} | ||
|
||
private static boolean setContains(@Nullable Set<String> set, String item) { | ||
if (set == null) { | ||
return false; | ||
} | ||
|
||
return set.contains(item); | ||
} | ||
} |
Oops, something went wrong.