Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Report status code before schema #338

Merged
merged 9 commits into from May 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -47,7 +47,7 @@ public class WebTauConfig {
private final ConfigValue disableFollowingRedirects = declareBoolean("disableRedirects", "disable following of redirects from HTTP calls");
private final ConfigValue maxRedirects = declare("maxRedirects", "Maximum number of redirects to follow for an HTTP call", () -> 20);
private final ConfigValue userAgent = declare("userAgent", "User agent to send on HTTP requests",
() -> "webtau/" + getClass().getPackage().getImplementationVersion());
() -> "webtau/" + WebTauMeta.getVersion());
private final ConfigValue removeWebtauFromUserAgent = declare("removeWebtauFromUserAgent",
"By default webtau appends webtau and its version to the user-agent, this disables that part",
() -> false);
Expand Down
Expand Up @@ -14,9 +14,7 @@
* limitations under the License.
*/

package com.twosigma.webtau.meta;

import com.twosigma.webtau.utils.ResourceUtils;
package com.twosigma.webtau.cfg;

public class WebTauMeta {
private static final WebTauMeta INSTANCE = new WebTauMeta();
Expand All @@ -27,6 +25,6 @@ public static String getVersion() {
}

private WebTauMeta() {
version = ResourceUtils.textContent("webtau.version").trim();
version = getClass().getPackage().getImplementationVersion();
}
}
7 changes: 0 additions & 7 deletions webtau-core/pom.xml
Expand Up @@ -53,13 +53,6 @@
</dependencies>

<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>

<plugins>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
Expand Down
1 change: 0 additions & 1 deletion webtau-core/src/main/resources/webtau.version

This file was deleted.

Expand Up @@ -44,13 +44,13 @@
"200": {
"description": "customer already exists",
"schema": {
"$ref": "#/definitions/Employee"
"$ref": "#/definitions/Id"
}
},
"201": {
"description": "customer created successfully",
"schema": {
"$ref": "#/definitions/Employee"
"$ref": "#/definitions/Id"
}
}
}
Expand All @@ -72,6 +72,17 @@
"type": "string"
}
}
},
"Id": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string"
}
}
}
}
}
Expand Up @@ -7,13 +7,13 @@
}, {
"scenario" : "disable request validation",
"stepsSummary" : {
"numberOfFailed" : 2
"numberOfSuccessful" : 3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we still need a failed case?

}
}, {
"scenario" : "disable response validation",
"stepsSummary" : {
"numberOfSuccessful" : 3
}
} ],
"exitCode" : 1
}
"exitCode" : 0
}
Expand Up @@ -16,7 +16,6 @@

package com.twosigma.webtau.cfg

import com.twosigma.webtau.meta.WebTauMeta
import org.apache.commons.cli.CommandLine
import org.apache.commons.cli.DefaultParser
import org.apache.commons.cli.HelpFormatter
Expand Down
Expand Up @@ -23,6 +23,8 @@ import com.twosigma.webtau.http.datanode.DataNode
import com.twosigma.webtau.http.datanode.GroovyDataNode
import com.twosigma.webtau.http.testserver.TestServerResponse
import com.twosigma.webtau.http.validation.HttpResponseValidator
import com.twosigma.webtau.http.validation.HttpValidationHandler
import com.twosigma.webtau.http.validation.HttpValidationHandlers
import com.twosigma.webtau.utils.ResourceUtils
import com.twosigma.webtau.utils.UrlUtils
import org.junit.*
Expand Down Expand Up @@ -982,6 +984,75 @@ class HttpGroovyTest implements HttpConfiguration {
http.lastValidationResult.errorMessage.should == ~/java.lang.IllegalArgumentException: Request header is null/
}

private static void withFailingHandler(Closure closure) {
HttpValidationHandler handler = { result -> throw new AssertionError((Object)"schema validation error") }
HttpValidationHandlers.withAdditionalHandler(handler, closure)
}

static String expected404 = '\n' +
'mismatches:\n' +
'\n' +
'header.statusCode: actual: 404 <java.lang.Integer>\n' +
' expected: 200 <java.lang.Integer>'

@Test
void "reports implicit status code mismatch instead of additional validator errors"() {
withFailingHandler {
code {
http.get("/notfound") {}
} should throwException(AssertionError, expected404)
}
}

@Test
void "reports explicit status code mismatch instead of additional validator errors"() {
withFailingHandler {
code {
http.get("/notfound") {
statusCode.should == 200
}
} should throwException(AssertionError, expected404)
}
}

@Test
void "reports status code mismatch instead of additional validator errors or failing body assertions"() {
withFailingHandler {
code {
http.get("/notfound") {
id.should == 'foo'
}
} should throwException(AssertionError, expected404)
}
}

@Test
void "reports body assertions instead of additional validation errors"() {
withFailingHandler() {
code {
http.get("/notfound") {
statusCode.should == 404
id.should == 'foo'
}
} should throwException(AssertionError, '\n' +
'mismatches:\n' +
'\n' +
'body.id: actual: null\n' +
' expected: "foo" <java.lang.String>')
}
}

@Test
void "reports additional validator errors if status code is correct"() {
withFailingHandler {
code {
http.get("/notfound") {
statusCode.should == 404
}
} should throwException(AssertionError, 'schema validation error')
}
}

@Override
String fullUrl(String url) {
if (UrlUtils.isFull(url)) {
Expand Down
4 changes: 2 additions & 2 deletions webtau-http/src/main/java/com/twosigma/webtau/http/Http.java
Expand Up @@ -436,8 +436,6 @@ private <R> R validateAndRecord(HttpValidationResult validationResult,
validationResult.setResponseHeaderNode(header);
validationResult.setResponseBodyNode(body);

HttpValidationHandlers.validate(validationResult);

ExpectationHandler recordAndThrowHandler = (valueMatcher, actualPath, actualValue, message) -> {
validationResult.addMismatch(message);
return ExpectationHandler.Flow.PassToNext;
Expand All @@ -458,6 +456,8 @@ private <R> R validateAndRecord(HttpValidationResult validationResult,
return null;
});

HttpValidationHandlers.validate(validationResult);

return extracted;
} catch (Throwable e) {
ExpectationHandlers.withAdditionalHandler((valueMatcher, actualPath, actualValue, message) -> {
Expand Down
Expand Up @@ -18,12 +18,34 @@

import com.twosigma.webtau.utils.ServiceLoaderUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Stream;

public class HttpValidationHandlers {
private static final List<HttpValidationHandler> configurations = ServiceLoaderUtils.load(HttpValidationHandler.class);
private static final List<HttpValidationHandler> globalHandlers = ServiceLoaderUtils.load(HttpValidationHandler.class);
private static final ThreadLocal<List<HttpValidationHandler>> localHandlers = ThreadLocal.withInitial(ArrayList::new);

public static <R> R withAdditionalHandler(HttpValidationHandler handler, Supplier<R> code) {
try {
addLocal(handler);
return code.get();
} finally {
removeLocal(handler);
}
}

public static void validate(HttpValidationResult validationResult) {
configurations.forEach(c -> c.validate(validationResult));
Stream.concat(localHandlers.get().stream(), globalHandlers.stream())
.forEach(c -> c.validate(validationResult));
}

private static void addLocal(HttpValidationHandler handler) {
localHandlers.get().add(handler);
}

private static void removeLocal(HttpValidationHandler handler) {
localHandlers.get().remove(handler);
}
}
Expand Up @@ -17,9 +17,9 @@
package com.twosigma.webtau.report;

import com.twosigma.webtau.cfg.ConfigValue;
import com.twosigma.webtau.cfg.WebTauMeta;
import com.twosigma.webtau.console.ConsoleOutputs;
import com.twosigma.webtau.console.ansi.Color;
import com.twosigma.webtau.meta.WebTauMeta;
import com.twosigma.webtau.utils.FileUtils;
import com.twosigma.webtau.utils.JsonUtils;
import com.twosigma.webtau.utils.ResourceUtils;
Expand Down