Skip to content

Commit

Permalink
[rewrite] #1281 a big moment, all tests green with graal-js
Browse files Browse the repository at this point in the history
reverted cookie expiry checks, felt karate should allow any kinds of bad cookies, as a testing tool
karate-jersey is done
previous commit has breaking changes to mock-servlet
of course http client in case anyone has extended is also a breaking change
now the remaining part is karate-ui which is not part of the maven build as tests
  • Loading branch information
ptrthomas committed Nov 11, 2020
1 parent 41fef71 commit a8f293c
Show file tree
Hide file tree
Showing 39 changed files with 323 additions and 602 deletions.
6 changes: 0 additions & 6 deletions karate-apache/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,6 @@
</exclusions>
</dependency>

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>${apache.httpcomponents.version}</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.intuit.karate.runtime.Config;
import com.intuit.karate.runtime.ScenarioEngine;
import com.intuit.karate.server.HttpClient;
import com.intuit.karate.server.HttpConstants;
import com.intuit.karate.server.HttpLogger;
import com.intuit.karate.server.HttpRequest;
import com.intuit.karate.server.Response;
Expand Down Expand Up @@ -83,6 +84,9 @@ public class ApacheHttpClient implements HttpClient, HttpRequestInterceptor {

private final ScenarioEngine engine;
private final Logger logger;
private final HttpLogger httpLogger;

private HttpClientBuilder clientBuilder;

public ApacheHttpClient(ScenarioEngine engine) {
this.engine = engine;
Expand All @@ -91,9 +95,6 @@ public ApacheHttpClient(ScenarioEngine engine) {
configure(engine.getConfig());
}

private HttpClientBuilder clientBuilder;
private final HttpLogger httpLogger;

private void configure(Config config) {
clientBuilder = HttpClientBuilder.create();
if (!config.isFollowRedirects()) {
Expand Down Expand Up @@ -218,7 +219,7 @@ public Response invoke(HttpRequest request) {
httpResponse = client.execute(requestBuilder.build());
HttpEntity responseEntity = httpResponse.getEntity();
if (responseEntity == null || responseEntity.getContent() == null) {
bytes = new byte[0];
bytes = HttpConstants.ZERO_BYTES;
} else {
InputStream is = responseEntity.getContent();
bytes = FileUtils.toBytes(is);
Expand Down
13 changes: 13 additions & 0 deletions karate-core/src/main/java/com/intuit/karate/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
Expand Down Expand Up @@ -343,6 +344,18 @@ public static InputStream toInputStream(String text) {
return new ByteArrayInputStream(text.getBytes(UTF8));
}

public static void deleteDirectory(File file) {
Path pathToBeDeleted = file.toPath();
try {
Files.walk(pathToBeDeleted)
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
} catch (Exception e) {
throw new RuntimeException();
}
}

public static String removeFileExtension(String path) {
int pos = path.lastIndexOf('.');
if (pos == -1) {
Expand Down
3 changes: 1 addition & 2 deletions karate-core/src/main/java/com/intuit/karate/Runner.java
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,7 @@ public Builder(RunnerOptions ro) {
paths = ro.getFeatures();
tags = ro.getTags();
scenarioName = ro.getName();
String envTemp = ro.getEnv();
env = envTemp == null ? StringUtils.trimToNull(System.getProperty("karate.env")) : envTemp;
env = ro.getEnv();
hooks = new ArrayList();
}

Expand Down
10 changes: 6 additions & 4 deletions karate-core/src/main/java/com/intuit/karate/SuiteRuntime.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@
*/
public class SuiteRuntime {

private String env; // lazy inited

public final String tagSelector;
public final Logger logger;
public final File workingDir;
Expand All @@ -63,6 +61,7 @@ public class SuiteRuntime {
public final String karateBase;
public final String karateConfig;

public String env; // can be lazy-inited
public String karateConfigEnv;

private String read(String name) {
Expand All @@ -87,6 +86,7 @@ public SuiteRuntime() {

public SuiteRuntime(Runner.Builder rb) {
env = rb.env;
karateConfigEnv = rb.env;
tagSelector = Tags.fromKarateOptionsTags(rb.tags);
logger = rb.logger;
workingDir = rb.workingDir;
Expand Down Expand Up @@ -139,10 +139,12 @@ public SuiteRuntime(Runner.Builder rb) {

private boolean envResolved;

public String getEnv() {
public String resolveEnv() {
if (!envResolved) {
envResolved = true;
env = StringUtils.trimToNull(System.getProperty("karate.env"));
if (env == null) {
env = StringUtils.trimToNull(System.getProperty("karate.env"));
}
if (env != null) {
logger.info("karate.env is: '{}'", env);
karateConfigEnv = read(karateConfigDir + "karate-config-" + env + ".js");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,18 +110,23 @@ public MockHandler(Feature feature, Map<String, Object> args) {
}
}
}
runtime.logger.info("mock server initialized: {}", featureName);
globals = runtime.engine.detachVariables();
runtime.logger.info("mock server initialized: {}", featureName);
}

private static final Result PASSED = Result.passed(0);

@Override
public Response handle(Request req) {
// important for graal to work properly
Thread.currentThread().setContextClassLoader(runtime.featureRuntime.suite.classLoader);
LOCAL_REQUEST.set(req);
req.processBody();
ScenarioEngine engine = new ScenarioEngine(runtime, new HashMap(globals));
// highly unlikely but support mocks calling other mocks in the same jvm
ScenarioEngine prevEngine = ScenarioEngine.get();
ScenarioEngine.set(engine);
engine.init();
engine.setVariable(ScenarioEngine.REQUEST_URL_BASE, req.getUrlBase());
engine.setVariable(ScenarioEngine.REQUEST_URI, req.getPath());
engine.setVariable(ScenarioEngine.REQUEST_METHOD, req.getMethod());
Expand All @@ -131,12 +136,8 @@ public Response handle(Request req) {
engine.setVariable(REQUEST_BYTES, req.getBody());
Map<String, List<Map<String, Object>>> files = req.getMultiPartFiles();
if (files != null) {
engine.setVariable(REQUEST_FILES, files); // TODO add to docs
engine.setHiddenVariable(REQUEST_FILES, files); // TODO add to docs
}
// highly unlikely but support mocks calling other mocks in the same jvm
ScenarioEngine prevEngine = ScenarioEngine.get();
ScenarioEngine.set(engine);
engine.init();
for (FeatureSection fs : feature.getSections()) {
if (fs.isOutline()) {
runtime.logger.warn("skipping scenario outline - {}:{}", featureName, fs.getScenarioOutline().getLine());
Expand All @@ -162,11 +163,11 @@ public Response handle(Request req) {
break;
}
}
Map<String, Variable> vars = engine.vars;
response = vars.remove(ScenarioEngine.RESPONSE);
responseStatus = vars.remove(ScenarioEngine.RESPONSE_STATUS);
responseHeaders = vars.remove(ScenarioEngine.RESPONSE_HEADERS);
responseDelay = vars.remove(RESPONSE_DELAY);
response = engine.vars.remove(ScenarioEngine.RESPONSE);
responseStatus = engine.vars.remove(ScenarioEngine.RESPONSE_STATUS);
responseHeaders = engine.vars.remove(ScenarioEngine.RESPONSE_HEADERS);
responseDelay = engine.vars.remove(RESPONSE_DELAY);
globals.putAll(engine.detachVariables());
} // END TRANSACTION ===========================================
ScenarioEngine.set(prevEngine);
if (result.isFailed()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ public ScenarioEngine getEngine() {
}

public String getEnv() {
return getEngine().runtime.featureRuntime.suite.getEnv();
return getEngine().runtime.featureRuntime.suite.resolveEnv();
}

public Object getInfo() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1043,7 +1043,7 @@ protected static KarateException fromJsEvalException(String js, Exception e) {
return new KarateException(sb.toString());
}

protected void setHiddenVariable(String key, Object value) {
public void setHiddenVariable(String key, Object value) {
if (value instanceof Variable) {
value = ((Variable) value).getValue();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ private Map<String, Object> initMagicVariables() {
}

public void beforeRun() {
String env = featureRuntime.suite.getEnv(); // this lazy-inits (one time) the suite env
String env = featureRuntime.suite.resolveEnv(); // this lazy-inits (one time) the suite env
if (appender == null) { // not perf, not debug
appender = APPENDER.get();
}
Expand Down
28 changes: 0 additions & 28 deletions karate-core/src/main/java/com/intuit/karate/server/Cookies.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@
import io.netty.handler.codec.http.cookie.CookieHeaderNames;
import io.netty.handler.codec.http.cookie.DefaultCookie;

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -59,11 +54,6 @@ private Cookies() {
private static final String SECURE = "secure";
private static final String HTTP_ONLY = "httponly";
private static final String SAME_SITE = "samesite";
private static final String EXPIRES = "expires";

public static final DateTimeFormatter DT_FMT_V1 = DateTimeFormatter.ofPattern("EEE, dd-MMM-yy HH:mm:ss z");
public static final DateTimeFormatter DT_FMT_V2 = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss z");
public static final DateTimeFormatter DTFMTR_RFC1123 = new DateTimeFormatterBuilder().appendOptional(DT_FMT_V1).appendOptional(DT_FMT_V2).toFormatter();

public static Map<String, Object> toMap(Cookie cookie) {
Map<String, Object> map = new HashMap();
Expand Down Expand Up @@ -116,12 +106,6 @@ public static Cookie fromMap(Map<String, Object> map) {
if (sameSite != null) {
cookie.setSameSite(CookieHeaderNames.SameSite.valueOf(sameSite));
}
String expirationDate = (String) map.get(EXPIRES);
if (isCookieExpired(expirationDate)) {
// force cookie to expire.
cookie.setMaxAge(0);
cookie.setValue("");
}
return cookie;
}

Expand All @@ -148,16 +132,4 @@ public static Map<String, Map> normalize(Object mapOrList) {
return cookies;
}

private static boolean isCookieExpired(String expirationDate) {
Date expiresDate = null;
if (expirationDate != null) {
try {
expiresDate = Date.from(ZonedDateTime.parse(expirationDate, DTFMTR_RFC1123).toInstant());
} catch (DateTimeParseException e) {
logger.warn("cookie 'expires' date parsing failed: {}", e.getMessage());
}
}
return expiresDate != null && !expiresDate.after(new Date());
}

}
24 changes: 18 additions & 6 deletions karate-core/src/main/java/com/intuit/karate/server/HttpLogger.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ public HttpLogger(Logger logger) {

private static void logHeaders(int num, String prefix, StringBuilder sb,
HttpLogModifier modifier, Map<String, List<String>> headers) {
if (headers == null) {
if (headers == null || headers.isEmpty()) {
return;
}
headers.forEach((k, v) -> {
sb.append('\n');
sb.append(num).append(prefix).append(k).append(": ");
int count = v.size();
if (count == 1) {
Expand All @@ -74,8 +75,8 @@ private static void logHeaders(int num, String prefix, StringBuilder sb,
sb.append(']');
}
}
sb.append('\n');
});
sb.append('\n');
}

private static void logBody(Config config, HttpLogModifier logModifier,
Expand All @@ -101,6 +102,12 @@ private static HttpLogModifier logModifier(Config config, String uri) {
return logModifier == null ? null : logModifier.enableForUri(uri) ? logModifier : null;
}

private static void appendLineFeedIfNeeded(StringBuilder sb) {
if (!Character.isSpaceChar(sb.charAt(sb.length() - 1))) {
sb.append('\n');
}
}

public static String getStatusFailureMessage(int expected, Config config, HttpRequest request, Response response) {
String url = request.getUrl();
HttpLogModifier logModifier = logModifier(config, url);
Expand All @@ -122,15 +129,19 @@ public void logRequest(Config config, HttpRequest request) {
String maskedUri = requestModifier == null ? uri : requestModifier.uri(uri);
StringBuilder sb = new StringBuilder();
sb.append("request:\n").append(requestCount).append(" > ")
.append(request.getMethod()).append(' ').append(maskedUri).append('\n');
.append(request.getMethod()).append(' ').append(maskedUri);
logHeaders(requestCount, " > ", sb, requestModifier, request.getHeaders());
ResourceType rt = ResourceType.fromContentType(request.getContentType());
if (rt == null || rt.isBinary()) {
// don't log body
} else {
Object converted = JsValue.fromBytes(request.getBody(), false);
Object converted = request.getBodyForDisplay();
if (converted == null) {
converted = JsValue.fromBytes(request.getBody(), false);
}
logBody(config, requestModifier, sb, uri, converted, true);
}
appendLineFeedIfNeeded(sb);
logger.debug("{}", sb);
}

Expand All @@ -141,15 +152,16 @@ public void logResponse(Config config, HttpRequest request, Response response) {
String uri = request.getUrl();
HttpLogModifier responseModifier = logModifier(config, uri);
sb.append("response time in milliseconds: ").append(elapsedTime).append('\n');
sb.append(requestCount).append(" < ").append(response.getStatus()).append('\n');
sb.append(requestCount).append(" < ").append(response.getStatus());
logHeaders(requestCount, " < ", sb, responseModifier, response.getHeaders());
ResourceType rt = response.getResourceType();
if (rt == null || rt.isBinary()) {
// don't log body
} else {
logBody(config, responseModifier, sb, uri, response.getBodyConverted(), false);
}
logger.debug("{}\n", sb);
appendLineFeedIfNeeded(sb);
logger.debug("{}", sb);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public class HttpRequest {
private String method;
private Map<String, List<String>> headers;
private byte[] body;
private String bodyForDisplay;

public void putHeader(String name, String... values) {
putHeader(name, Arrays.asList(values));
Expand Down Expand Up @@ -107,6 +108,14 @@ public void setBody(byte[] body) {
this.body = body;
}

public String getBodyForDisplay() {
return bodyForDisplay;
}

public void setBodyForDisplay(String bodyForDisplay) {
this.bodyForDisplay = bodyForDisplay;
}

public List<String> getHeaderValues(String name) { // TOTO optimize
return StringUtils.getIgnoreKeyCase(headers, name);
}
Expand Down
Loading

0 comments on commit a8f293c

Please sign in to comment.