[OLINGO-935] improved debug support
including more unit tests Signed-off-by: Christian Amend <christian.amend@sap.com>
This commit is contained in:
parent
1600684d4f
commit
9e67d0e3e8
|
@ -23,7 +23,6 @@ import java.io.InputStream;
|
|||
import java.io.Writer;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.olingo.commons.api.ex.ODataRuntimeException;
|
||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.deserializer.DeserializerException;
|
||||
|
@ -70,33 +69,12 @@ public class DebugTabBody implements DebugTab {
|
|||
return "Body";
|
||||
}
|
||||
|
||||
//
|
||||
@Override
|
||||
public void appendJson(final JsonGenerator gen) throws IOException {
|
||||
public void appendJson(final JsonGenerator json) throws IOException {
|
||||
if (response == null || response.getContent() == null) {
|
||||
gen.writeNull();
|
||||
json.writeNull();
|
||||
} else {
|
||||
gen.writeString(getContentString());
|
||||
}
|
||||
}
|
||||
|
||||
private String getContentString() {
|
||||
try {
|
||||
String contentString;
|
||||
switch (responseContent) {
|
||||
case IMAGE:
|
||||
contentString = Base64.encodeBase64String(streamToBytes(response.getContent()));
|
||||
break;
|
||||
case JSON:
|
||||
case XML:
|
||||
case TEXT:
|
||||
default:
|
||||
contentString = new String(streamToBytes(response.getContent()), "UTF-8");
|
||||
break;
|
||||
}
|
||||
return contentString;
|
||||
} catch (IOException e) {
|
||||
return "Could not parse Body for Debug Output";
|
||||
json.writeString(getContentString());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,12 +108,23 @@ public class DebugTabBody implements DebugTab {
|
|||
}
|
||||
}
|
||||
|
||||
private byte[] streamToBytes(final InputStream input) {
|
||||
private String getContentString() {
|
||||
try {
|
||||
final byte[] content = streamToBytes(response.getContent());
|
||||
return responseContent == ResponseContent.IMAGE ?
|
||||
Base64.encodeBase64String(content) :
|
||||
new String(content, "UTF-8");
|
||||
} catch (final IOException e) {
|
||||
return "Could not parse Body for Debug Output";
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] streamToBytes(final InputStream input) throws IOException {
|
||||
if (input != null) {
|
||||
try {
|
||||
return new FixedFormatDeserializerImpl().binary(input);
|
||||
} catch (final DeserializerException e) {
|
||||
throw new ODataRuntimeException("Error on reading request content", e);
|
||||
throw new IOException("Error on reading request content", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -65,12 +65,12 @@ public class DebugTabRuntime implements DebugTab {
|
|||
private void appendJsonNode(final JsonGenerator gen, final RuntimeNode node) throws IOException {
|
||||
gen.writeStartObject();
|
||||
gen.writeStringField("class", node.className);
|
||||
gen.writeStringField("method ", node.methodName);
|
||||
gen.writeStringField("method", node.methodName);
|
||||
|
||||
if (node.timeStopped == 0) {
|
||||
gen.writeNullField("duration");
|
||||
} else {
|
||||
gen.writeStringField("duration", Long.toString((node.timeStopped - node.timeStarted) / TO_MILLIS_DIVISOR));
|
||||
gen.writeNumberField("duration", (node.timeStopped - node.timeStarted) / TO_MILLIS_DIVISOR);
|
||||
gen.writeStringField("unit", "µs");
|
||||
}
|
||||
|
||||
|
@ -140,7 +140,9 @@ public class DebugTabRuntime implements DebugTab {
|
|||
|
||||
protected boolean add(final RuntimeMeasurement runtimeMeasurement) {
|
||||
if (timeStarted <= runtimeMeasurement.getTimeStarted()
|
||||
&& timeStopped != 0 && timeStopped >= runtimeMeasurement.getTimeStopped()) {
|
||||
&& timeStopped != 0
|
||||
&& timeStopped > runtimeMeasurement.getTimeStarted() // in case the stop time has not been set
|
||||
&& timeStopped >= runtimeMeasurement.getTimeStopped()) {
|
||||
for (RuntimeNode candidate : children) {
|
||||
if (candidate.add(runtimeMeasurement)) {
|
||||
return true;
|
||||
|
|
|
@ -90,7 +90,7 @@ public class DebugTabStacktrace implements DebugTab {
|
|||
gen.writeStartObject();
|
||||
gen.writeStringField("class", element.getClassName());
|
||||
gen.writeStringField("method", element.getMethodName());
|
||||
gen.writeStringField("line", Integer.toString(element.getLineNumber()));
|
||||
gen.writeNumberField("line", element.getLineNumber());
|
||||
gen.writeEndObject();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,15 +25,18 @@ import java.util.LinkedHashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.EdmType;
|
||||
import org.apache.olingo.commons.api.ex.ODataException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.api.uri.UriInfoKind;
|
||||
import org.apache.olingo.server.api.uri.UriParameter;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.UriResourceComplexProperty;
|
||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||
import org.apache.olingo.server.api.uri.UriResourceFunction;
|
||||
import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
||||
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
|
||||
import org.apache.olingo.server.api.uri.UriResourceSingleton;
|
||||
import org.apache.olingo.server.api.uri.queryoption.ApplyItem;
|
||||
import org.apache.olingo.server.api.uri.queryoption.ApplyOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.CountOption;
|
||||
|
@ -92,6 +95,15 @@ public class DebugTabUri implements DebugTab {
|
|||
if (uriInfo.getKind() == UriInfoKind.resource) {
|
||||
gen.writeFieldName("uriResourceParts");
|
||||
appendURIResourceParts(gen, uriInfo.getUriResourceParts());
|
||||
} else if (uriInfo.getKind() == UriInfoKind.crossjoin) {
|
||||
gen.writeFieldName("entitySetNames");
|
||||
gen.writeStartArray();
|
||||
for (final String name : uriInfo.asUriInfoCrossjoin().getEntitySetNames()) {
|
||||
gen.writeString(name);
|
||||
}
|
||||
gen.writeEndArray();
|
||||
} else if (uriInfo.getKind() == UriInfoKind.entityId) {
|
||||
appendType(gen, "typeCast", uriInfo.asUriInfoEntityId().getEntityTypeCast());
|
||||
}
|
||||
|
||||
if (uriInfo.getFormatOption() != null) {
|
||||
|
@ -183,23 +195,39 @@ public class DebugTabUri implements DebugTab {
|
|||
gen.writeStartObject();
|
||||
gen.writeStringField("uriResourceKind", resource.getKind().toString());
|
||||
gen.writeStringField("segment", resource.toString());
|
||||
if (resource instanceof UriResourcePartTyped && ((UriResourcePartTyped) resource).getType() != null) {
|
||||
gen.writeStringField("type",
|
||||
((UriResourcePartTyped) resource).getType().getFullQualifiedName().getFullQualifiedNameAsString());
|
||||
if (resource instanceof UriResourcePartTyped) {
|
||||
appendType(gen, "type", ((UriResourcePartTyped) resource).getType());
|
||||
gen.writeBooleanField("isCollection", ((UriResourcePartTyped) resource).isCollection());
|
||||
}
|
||||
if (resource instanceof UriResourceEntitySet) {
|
||||
appendParameters(gen, "keys", ((UriResourceEntitySet) resource).getKeyPredicates());
|
||||
appendType(gen, "typeFilterOnCollection", ((UriResourceEntitySet) resource).getTypeFilterOnCollection());
|
||||
appendType(gen, "typeFilterOnEntry", ((UriResourceEntitySet) resource).getTypeFilterOnEntry());
|
||||
} else if (resource instanceof UriResourceNavigation) {
|
||||
appendParameters(gen, "keys", ((UriResourceNavigation) resource).getKeyPredicates());
|
||||
appendType(gen, "typeFilterOnCollection", ((UriResourceNavigation) resource).getTypeFilterOnCollection());
|
||||
appendType(gen, "typeFilterOnEntry", ((UriResourceNavigation) resource).getTypeFilterOnEntry());
|
||||
} else if (resource instanceof UriResourceFunction) {
|
||||
appendParameters(gen, "parameters", ((UriResourceFunction) resource).getParameters());
|
||||
appendParameters(gen, "keys", ((UriResourceFunction) resource).getKeyPredicates());
|
||||
appendType(gen, "typeFilterOnCollection", ((UriResourceFunction) resource).getTypeFilterOnCollection());
|
||||
appendType(gen, "typeFilterOnEntry", ((UriResourceFunction) resource).getTypeFilterOnEntry());
|
||||
} else if (resource instanceof UriResourceSingleton) {
|
||||
appendType(gen, "typeFilter", ((UriResourceSingleton) resource).getEntityTypeFilter());
|
||||
} else if (resource instanceof UriResourceComplexProperty) {
|
||||
appendType(gen, "typeFilter", ((UriResourceComplexProperty) resource).getComplexTypeFilter());
|
||||
}
|
||||
gen.writeEndObject();
|
||||
}
|
||||
gen.writeEndArray();
|
||||
}
|
||||
|
||||
private void appendType(JsonGenerator json, final String name, final EdmType type) throws IOException {
|
||||
if (type != null) {
|
||||
json.writeStringField(name, type.getFullQualifiedName().getFullQualifiedNameAsString());
|
||||
}
|
||||
}
|
||||
|
||||
private void appendParameters(final JsonGenerator gen, final String name, final List<UriParameter> parameters)
|
||||
throws IOException {
|
||||
if (!parameters.isEmpty()) {
|
||||
|
@ -260,7 +288,7 @@ public class DebugTabUri implements DebugTab {
|
|||
|
||||
appendCommonJsonObjects(gen, item.getCountOption(), item.getSkipOption(), item.getTopOption(),
|
||||
item.getFilterOption(), item.getOrderByOption(), item.getSelectOption(), item.getExpandOption(),
|
||||
item.getSearchOption(), null); // TODO: item.getApplyOption()
|
||||
item.getSearchOption(), item.getApplyOption());
|
||||
|
||||
gen.writeEndObject();
|
||||
}
|
||||
|
@ -476,8 +504,21 @@ public class DebugTabUri implements DebugTab {
|
|||
appendURIResourceParts(json, uriInfo.getUriResourceParts());
|
||||
json.close();
|
||||
writer.append("\n</li>\n</ul>\n");
|
||||
} else if (uriInfo.getKind() == UriInfoKind.crossjoin) {
|
||||
writer.append("<h2>Crossjoin EntitySet Names</h2>\n")
|
||||
.append("<ul>\n");
|
||||
for (final String name : uriInfo.asUriInfoCrossjoin().getEntitySetNames()) {
|
||||
writer.append("<li>").append(name).append("</li>\n");
|
||||
}
|
||||
writer.append("</ul>\n");
|
||||
} else {
|
||||
writer.append("<h2>Kind</h2>\n<p>").append(uriInfo.getKind().name()).append("</p>\n");
|
||||
if (uriInfo.getKind() == UriInfoKind.entityId && uriInfo.asUriInfoEntityId().getEntityTypeCast() != null) {
|
||||
writer.append("<h2>Type Cast</h2>\n<p>")
|
||||
.append(uriInfo.asUriInfoEntityId().getEntityTypeCast().getFullQualifiedName()
|
||||
.getFullQualifiedNameAsString())
|
||||
.append("</p>\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (uriInfo.getSearchOption() != null) {
|
||||
|
|
|
@ -18,17 +18,22 @@
|
|||
*/
|
||||
package org.apache.olingo.server.core.debug;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.EdmEnumType;
|
||||
import org.apache.olingo.commons.api.edm.EdmType;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.uri.UriParameter;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.UriResourceComplexProperty;
|
||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||
import org.apache.olingo.server.api.uri.UriResourceFunction;
|
||||
import org.apache.olingo.server.api.uri.UriResourceIt;
|
||||
import org.apache.olingo.server.api.uri.UriResourceLambdaAll;
|
||||
import org.apache.olingo.server.api.uri.UriResourceLambdaAny;
|
||||
import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
||||
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
|
||||
import org.apache.olingo.server.api.uri.UriResourceSingleton;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
|
||||
|
@ -38,7 +43,10 @@ import org.apache.olingo.server.api.uri.queryoption.expression.Member;
|
|||
import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.UnaryOperatorKind;
|
||||
|
||||
import java.util.List;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
|
||||
/**
|
||||
* A custom expression visitor which converts the tree into a {@link JsonNode} tree.
|
||||
|
@ -76,6 +84,10 @@ public class ExpressionJsonVisitor implements ExpressionVisitor<JsonNode> {
|
|||
private static final String TYPE_NAME = "type";
|
||||
private static final String OPERATOR_NAME = "operator";
|
||||
private static final String NODE_TYPE_NAME = "nodeType";
|
||||
private static final String KEYS_NAME = "keys";
|
||||
private static final String TYPE_FILTER_NAME = "typeFilter";
|
||||
private static final String TYPE_FILTER_ON_COLLECTION_NAME = "typeFilterOnCollection";
|
||||
private static final String TYPE_FILTER_ON_ENTRY_NAME = "typeFilterOnEntry";
|
||||
|
||||
private final JsonNodeFactory nodeFactory = JsonNodeFactory.instance;
|
||||
|
||||
|
@ -140,6 +152,7 @@ public class ExpressionJsonVisitor implements ExpressionVisitor<JsonNode> {
|
|||
ObjectNode result = nodeFactory.objectNode()
|
||||
.put(NODE_TYPE_NAME, MEMBER_NAME)
|
||||
.put(TYPE_NAME, getType(lastSegment));
|
||||
putType(result, TYPE_FILTER_NAME, member.getStartTypeFilter());
|
||||
ArrayNode segments = result.putArray(RESOURCE_SEGMENTS_NAME);
|
||||
for (final UriResource segment : uriResourceParts) {
|
||||
if (segment instanceof UriResourceLambdaAll) {
|
||||
|
@ -149,10 +162,32 @@ public class ExpressionJsonVisitor implements ExpressionVisitor<JsonNode> {
|
|||
final UriResourceLambdaAny any = (UriResourceLambdaAny) segment;
|
||||
segments.add(visitLambdaExpression(ANY_NAME, any.getLambdaVariable(), any.getExpression()));
|
||||
} else if (segment instanceof UriResourcePartTyped) {
|
||||
segments.add(nodeFactory.objectNode()
|
||||
ObjectNode node = nodeFactory.objectNode()
|
||||
.put(NODE_TYPE_NAME, segment.getKind().toString())
|
||||
.put(NAME_NAME, segment.toString())
|
||||
.put(TYPE_NAME, getType(segment)));
|
||||
.put(TYPE_NAME, getType(segment));
|
||||
if (segment instanceof UriResourceEntitySet) {
|
||||
putParameters(node, KEYS_NAME, ((UriResourceEntitySet) segment).getKeyPredicates());
|
||||
putType(node, TYPE_FILTER_ON_COLLECTION_NAME, ((UriResourceEntitySet) segment).getTypeFilterOnCollection());
|
||||
putType(node, TYPE_FILTER_ON_ENTRY_NAME, ((UriResourceEntitySet) segment).getTypeFilterOnEntry());
|
||||
} else if (segment instanceof UriResourceNavigation) {
|
||||
putParameters(node, KEYS_NAME, ((UriResourceNavigation) segment).getKeyPredicates());
|
||||
putType(node, TYPE_FILTER_ON_COLLECTION_NAME, ((UriResourceNavigation) segment).getTypeFilterOnCollection());
|
||||
putType(node, TYPE_FILTER_ON_ENTRY_NAME, ((UriResourceNavigation) segment).getTypeFilterOnEntry());
|
||||
} else if (segment instanceof UriResourceFunction) {
|
||||
putParameters(node, PARAMETERS_NAME, ((UriResourceFunction) segment).getParameters());
|
||||
putParameters(node, KEYS_NAME, ((UriResourceFunction) segment).getKeyPredicates());
|
||||
putType(node, TYPE_FILTER_ON_COLLECTION_NAME, ((UriResourceFunction) segment).getTypeFilterOnCollection());
|
||||
putType(node, TYPE_FILTER_ON_ENTRY_NAME, ((UriResourceFunction) segment).getTypeFilterOnEntry());
|
||||
} else if (segment instanceof UriResourceIt) {
|
||||
putType(node, TYPE_FILTER_ON_COLLECTION_NAME, ((UriResourceIt) segment).getTypeFilterOnCollection());
|
||||
putType(node, TYPE_FILTER_ON_ENTRY_NAME, ((UriResourceIt) segment).getTypeFilterOnEntry());
|
||||
} else if (segment instanceof UriResourceSingleton) {
|
||||
putType(node, TYPE_FILTER_NAME, ((UriResourceSingleton) segment).getEntityTypeFilter());
|
||||
} else if (segment instanceof UriResourceComplexProperty) {
|
||||
putType(node, TYPE_FILTER_NAME, ((UriResourceComplexProperty) segment).getComplexTypeFilter());
|
||||
}
|
||||
segments.add(node);
|
||||
} else {
|
||||
segments.add(nodeFactory.objectNode()
|
||||
.put(NODE_TYPE_NAME, segment.getKind().toString())
|
||||
|
@ -163,6 +198,22 @@ public class ExpressionJsonVisitor implements ExpressionVisitor<JsonNode> {
|
|||
return result;
|
||||
}
|
||||
|
||||
private void putType(ObjectNode node, final String name, final EdmType type) {
|
||||
if (type != null) {
|
||||
node.put(name, type.getFullQualifiedName().getFullQualifiedNameAsString());
|
||||
}
|
||||
}
|
||||
|
||||
private void putParameters(ObjectNode node, final String name, final List<UriParameter> parameters) {
|
||||
if (!parameters.isEmpty()) {
|
||||
ObjectNode parametersNode = node.putObject(name);
|
||||
for (final UriParameter parameter : parameters) {
|
||||
parametersNode.put(parameter.getName(),
|
||||
parameter.getText() == null ? parameter.getAlias() : parameter.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonNode visitAlias(final String aliasName) throws ExpressionVisitException, ODataApplicationException {
|
||||
return nodeFactory.objectNode()
|
||||
|
@ -186,8 +237,8 @@ public class ExpressionJsonVisitor implements ExpressionVisitor<JsonNode> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public JsonNode visitEnum(final EdmEnumType type, final List<String> enumValues) throws ExpressionVisitException,
|
||||
ODataApplicationException {
|
||||
public JsonNode visitEnum(final EdmEnumType type, final List<String> enumValues)
|
||||
throws ExpressionVisitException, ODataApplicationException {
|
||||
ObjectNode result = nodeFactory.objectNode()
|
||||
.put(NODE_TYPE_NAME, ENUM_NAME)
|
||||
.put(TYPE_NAME, getTypeString(type));
|
||||
|
@ -206,9 +257,8 @@ public class ExpressionJsonVisitor implements ExpressionVisitor<JsonNode> {
|
|||
return NUMBER_NAME;
|
||||
case NOT:
|
||||
return BOOLEAN_NAME;
|
||||
default:
|
||||
return UNKNOWN_NAME;
|
||||
}
|
||||
return UNKNOWN_NAME;
|
||||
}
|
||||
|
||||
private String getType(final MethodKind methodCall) {
|
||||
|
@ -257,9 +307,9 @@ public class ExpressionJsonVisitor implements ExpressionVisitor<JsonNode> {
|
|||
return DATETIMEOFFSET_NAME;
|
||||
|
||||
case CAST:
|
||||
default:
|
||||
return UNKNOWN_NAME;
|
||||
}
|
||||
return UNKNOWN_NAME;
|
||||
}
|
||||
|
||||
private String getType(final BinaryOperatorKind operator) {
|
||||
|
@ -281,10 +331,8 @@ public class ExpressionJsonVisitor implements ExpressionVisitor<JsonNode> {
|
|||
case AND:
|
||||
case OR:
|
||||
return BOOLEAN_NAME;
|
||||
|
||||
default:
|
||||
return UNKNOWN_NAME;
|
||||
}
|
||||
return UNKNOWN_NAME;
|
||||
}
|
||||
|
||||
private String getTypeString(final EdmType type) {
|
||||
|
|
|
@ -21,24 +21,30 @@ package org.apache.olingo.server.core.debug;
|
|||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
public abstract class AbstractDebugTabTest {
|
||||
|
||||
protected String createHtml(final DebugTab tab) throws IOException {
|
||||
StringWriter writer = new StringWriter();
|
||||
tab.appendHtml(writer);
|
||||
writer.flush();
|
||||
return writer.toString();
|
||||
protected String createHtml(DebugTab tab) throws IOException {
|
||||
return create(tab, true);
|
||||
}
|
||||
|
||||
protected String createJson(final DebugTab tab) throws IOException {
|
||||
protected String createJson(DebugTab tab) throws IOException {
|
||||
return create(tab, false);
|
||||
}
|
||||
|
||||
private String create(DebugTab tab, final boolean html) throws IOException {
|
||||
StringWriter writer = new StringWriter();
|
||||
JsonGenerator gen = new JsonFactory().createGenerator(writer);
|
||||
tab.appendJson(gen);
|
||||
gen.flush();
|
||||
gen.close();
|
||||
if (html) {
|
||||
tab.appendHtml(writer);
|
||||
} else {
|
||||
// Create JSON generator (the object mapper is necessary to write expression trees).
|
||||
JsonGenerator json = new ObjectMapper().getFactory().createGenerator(writer);
|
||||
tab.appendJson(json);
|
||||
json.flush();
|
||||
json.close();
|
||||
}
|
||||
writer.flush();
|
||||
return writer.toString();
|
||||
}
|
||||
|
|
|
@ -20,6 +20,14 @@ package org.apache.olingo.server.core.debug;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DebugTabBodyTest extends AbstractDebugTabTest {
|
||||
|
@ -31,4 +39,63 @@ public class DebugTabBodyTest extends AbstractDebugTabTest {
|
|||
assertEquals("null", createJson(tab));
|
||||
assertEquals("<pre class=\"code\">\nODataLibrary: No body.\n</pre>\n", createHtml(tab));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void json() throws Exception {
|
||||
ODataResponse response = new ODataResponse();
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, ContentType.JSON_NO_METADATA.toContentTypeString());
|
||||
response.setContent(IOUtils.toInputStream("{\"property\": true}"));
|
||||
assertEquals("\"{\\\"property\\\": true}\"", createJson(new DebugTabBody(response)));
|
||||
|
||||
response.setContent(IOUtils.toInputStream("{\"property\": false}"));
|
||||
assertEquals("<pre class=\"code json\">\n{\"property\": false}\n</pre>\n", createHtml(new DebugTabBody(response)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void xml() throws Exception {
|
||||
ODataResponse response = new ODataResponse();
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, ContentType.APPLICATION_XML.toContentTypeString());
|
||||
response.setContent(IOUtils.toInputStream("<?xml version='1.1'?>\n<a xmlns=\"b\" />\n"));
|
||||
assertEquals("\"<?xml version='1.1'?>\\n<a xmlns=\\\"b\\\" />\\n\"", createJson(new DebugTabBody(response)));
|
||||
|
||||
response.setContent(IOUtils.toInputStream("<?xml version='1.1'?>\n<c xmlns=\"d\" />\n"));
|
||||
assertEquals("<pre class=\"code xml\">\n<?xml version='1.1'?>\n<c xmlns=\"d\" />\n\n</pre>\n",
|
||||
createHtml(new DebugTabBody(response)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void text() throws Exception {
|
||||
ODataResponse response = new ODataResponse();
|
||||
response.setContent(IOUtils.toInputStream("testText\n12"));
|
||||
assertEquals("\"testText\\n12\"", createJson(new DebugTabBody(response)));
|
||||
|
||||
response.setContent(IOUtils.toInputStream("testText\n34"));
|
||||
assertEquals("<pre class=\"code\">\ntestText\n34\n</pre>\n", createHtml(new DebugTabBody(response)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void image() throws Exception {
|
||||
ODataResponse response = new ODataResponse();
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, "image/png");
|
||||
response.setContent(new ByteArrayInputStream(new byte[] { -1, -2, -3, -4 }));
|
||||
assertEquals("\"//79/A==\"", createJson(new DebugTabBody(response)));
|
||||
|
||||
response.setContent(new ByteArrayInputStream(new byte[] { -5, -6, -7, -8 }));
|
||||
assertEquals("<img src=\"data:image/png;base64,+/r5+A==\" />\n", createHtml(new DebugTabBody(response)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void streamError() throws Exception {
|
||||
ODataResponse response = new ODataResponse();
|
||||
InputStream input = new InputStream() {
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
throw new IOException("test");
|
||||
}
|
||||
};
|
||||
response.setContent(input);
|
||||
assertEquals("\"Could not parse Body for Debug Output\"", createJson(new DebugTabBody(response)));
|
||||
assertEquals("<pre class=\"code\">\nCould not parse Body for Debug Output\n</pre>\n",
|
||||
createHtml(new DebugTabBody(response)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.olingo.server.core.debug;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.olingo.server.api.debug.RuntimeMeasurement;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DebugTabRuntimeTest extends AbstractDebugTabTest {
|
||||
|
||||
@Test
|
||||
public void runtime() throws Exception {
|
||||
final DebugTabRuntime tab = new DebugTabRuntime(Arrays.asList(
|
||||
createMeasurement("class1", "method1", 0, 42),
|
||||
createMeasurement("class2", "method2", 12, 23),
|
||||
createMeasurement("class2", "method2", 24, 26),
|
||||
createMeasurement("class3", "method3", 98, 0)));
|
||||
assertEquals("[{\"class\":\"class1\",\"method\":\"method1\",\"duration\":42,\"unit\":\"µs\",\"children\":["
|
||||
+ "{\"class\":\"class2\",\"method\":\"method2\",\"duration\":13,\"unit\":\"µs\"}]},"
|
||||
+ "{\"class\":\"class3\",\"method\":\"method3\",\"duration\":null}]",
|
||||
createJson(tab));
|
||||
|
||||
assertEquals("<ol class=\"tree\">\n"
|
||||
+ "<li>\n"
|
||||
+ "<span class=\"code\"><span class=\"draw\">├─ </span>"
|
||||
+ "<span class=\"class\">class1</span>.<span class=\"method\">method1(…)</span>"
|
||||
+ "</span><span class=\"numeric\" title=\"Gross duration\">42 µs</span>\n"
|
||||
+ "<ol class=\"tree\">\n"
|
||||
+ "<li>\n"
|
||||
+ "<span class=\"code\"><span class=\"draw\">│ └─ </span>"
|
||||
+ "<span class=\"class\">class2</span>.<span class=\"method\">method2(…)</span>"
|
||||
+ "</span><span class=\"numeric\" title=\"Gross duration\">13 µs</span>\n"
|
||||
+ "</li>\n"
|
||||
+ "</ol>\n"
|
||||
+ "</li>\n"
|
||||
+ "<li>\n"
|
||||
+ "<span class=\"code\"><span class=\"draw\">└─ </span>"
|
||||
+ "<span class=\"class\">class3</span>.<span class=\"method\">method3(…)</span>"
|
||||
+ "</span><span class=\"null\" title=\"Stop time missing\">unfinished</span>\n"
|
||||
+ "</li>\n"
|
||||
+ "</ol>\n",
|
||||
createHtml(tab));
|
||||
}
|
||||
|
||||
private RuntimeMeasurement createMeasurement(final String className, final String methodName,
|
||||
final int startMilliseconds, final int stopMilliseconds) {
|
||||
RuntimeMeasurement measurement = new RuntimeMeasurement();
|
||||
measurement.setClassName(className);
|
||||
measurement.setMethodName(methodName);
|
||||
measurement.setTimeStarted(startMilliseconds * 1000);
|
||||
measurement.setTimeStopped(stopMilliseconds * 1000);
|
||||
return measurement;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.olingo.server.core.debug;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class DebugTabStacktraceTest extends AbstractDebugTabTest {
|
||||
|
||||
@Test
|
||||
public void stacktrace() throws Exception {
|
||||
Exception cause = new Exception("innerError");
|
||||
cause.setStackTrace(new StackTraceElement[] {
|
||||
new StackTraceElement("inner.class", "inner.method", "inner/filename", 99) });
|
||||
Exception exception = new Exception("error", cause);
|
||||
exception.setStackTrace(new StackTraceElement[] {
|
||||
new StackTraceElement("some.class", "some.method", "filename", 42),
|
||||
cause.getStackTrace()[0] });
|
||||
final DebugTabStacktrace tab = new DebugTabStacktrace(exception);
|
||||
assertEquals("{\"exceptions\":["
|
||||
+ "{\"class\":\"java.lang.Exception\",\"message\":\"error\","
|
||||
+ "\"invocation\":{\"class\":\"some.class\",\"method\":\"some.method\",\"line\":42}},"
|
||||
+ "{\"class\":\"java.lang.Exception\",\"message\":\"innerError\","
|
||||
+ "\"invocation\":{\"class\":\"inner.class\",\"method\":\"inner.method\",\"line\":99}}],"
|
||||
+ "\"stacktrace\":["
|
||||
+ "{\"class\":\"some.class\",\"method\":\"some.method\",\"line\":42},"
|
||||
+ "{\"class\":\"inner.class\",\"method\":\"inner.method\",\"line\":99}]}",
|
||||
createJson(tab));
|
||||
|
||||
assertEquals("<h2>java.lang.Exception</h2>\n"
|
||||
+ "<p>innerError</p>\n"
|
||||
+ "<table>\n"
|
||||
+ "<thead>\n"
|
||||
+ "<tr>\n"
|
||||
+ "<th class=\"name\">Class</th>\n"
|
||||
+ "<th class=\"name\">Method</th>\n"
|
||||
+ "<th class=\"value\">Line number in class</th>\n"
|
||||
+ "</tr>\n"
|
||||
+ "</thead>\n"
|
||||
+ "<tbody>\n"
|
||||
+ "<tr>\n"
|
||||
+ "<td class=\"name\">inner.class</td>\n"
|
||||
+ "<td class=\"name\">inner.method</td>\n"
|
||||
+ "<td class=\"value\">99</td>\n"
|
||||
+ "</tr>\n"
|
||||
+ "</tbody>\n"
|
||||
+ "</table>\n"
|
||||
+ "<h2>java.lang.Exception</h2>\n"
|
||||
+ "<p>error</p>\n"
|
||||
+ "<table>\n"
|
||||
+ "<thead>\n"
|
||||
+ "<tr>\n"
|
||||
+ "<th class=\"name\">Class</th>\n"
|
||||
+ "<th class=\"name\">Method</th>\n"
|
||||
+ "<th class=\"value\">Line number in class</th>\n"
|
||||
+ "</tr>\n"
|
||||
+ "</thead>\n"
|
||||
+ "<tbody>\n"
|
||||
+ "<tr>\n"
|
||||
+ "<td class=\"name\">some.class</td>\n"
|
||||
+ "<td class=\"name\">some.method</td>\n"
|
||||
+ "<td class=\"value\">42</td>\n"
|
||||
+ "</tr>\n"
|
||||
+ "</tbody>\n"
|
||||
+ "</table>\n"
|
||||
+ "<h2>Stacktrace</h2>\n"
|
||||
+ "<table>\n"
|
||||
+ "<thead>\n"
|
||||
+ "<tr>\n"
|
||||
+ "<th class=\"name\">Class</th>\n"
|
||||
+ "<th class=\"name\">Method</th>\n"
|
||||
+ "<th class=\"value\">Line number in class</th>\n"
|
||||
+ "</tr>\n"
|
||||
+ "</thead>\n"
|
||||
+ "<tbody>\n"
|
||||
+ "<tr>\n"
|
||||
+ "<td class=\"name\">some.class</td>\n"
|
||||
+ "<td class=\"name\">some.method</td>\n"
|
||||
+ "<td class=\"value\">42</td>\n"
|
||||
+ "</tr>\n"
|
||||
+ "<tr>\n"
|
||||
+ "<td class=\"name\">inner.class</td>\n"
|
||||
+ "<td class=\"name\">inner.method</td>\n"
|
||||
+ "<td class=\"value\">99</td>\n"
|
||||
+ "</tr>\n"
|
||||
+ "</tbody>\n"
|
||||
+ "</table>\n",
|
||||
createHtml(tab));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,405 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.olingo.server.core.debug;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.allOf;
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.endsWith;
|
||||
import static org.hamcrest.CoreMatchers.startsWith;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.edm.EdmFunction;
|
||||
import org.apache.olingo.commons.api.edm.EdmFunctionImport;
|
||||
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.api.edm.EdmReturnType;
|
||||
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
||||
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
|
||||
import org.apache.olingo.server.api.uri.UriInfoKind;
|
||||
import org.apache.olingo.server.api.uri.UriParameter;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SelectItem;
|
||||
import org.apache.olingo.server.api.uri.queryoption.apply.AggregateExpression.StandardMethod;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind;
|
||||
import org.apache.olingo.server.core.uri.UriInfoImpl;
|
||||
import org.apache.olingo.server.core.uri.UriParameterImpl;
|
||||
import org.apache.olingo.server.core.uri.UriResourceEntitySetImpl;
|
||||
import org.apache.olingo.server.core.uri.UriResourceFunctionImpl;
|
||||
import org.apache.olingo.server.core.uri.UriResourceNavigationPropertyImpl;
|
||||
import org.apache.olingo.server.core.uri.UriResourcePrimitivePropertyImpl;
|
||||
import org.apache.olingo.server.core.uri.parser.search.SearchTermImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.AliasQueryOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.ApplyOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.CountOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.CustomQueryOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.ExpandItemImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.ExpandOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.FilterOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.FormatOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.IdOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.LevelsOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.OrderByItemImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.OrderByOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.SearchOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.SelectItemImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.SelectOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.SkipOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.SkipTokenOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.TopOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.apply.AggregateExpressionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.apply.AggregateImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.apply.GroupByImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.apply.GroupByItemImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.expression.BinaryImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.expression.LiteralImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.expression.MemberImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.expression.MethodImpl;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DebugTabUriTest extends AbstractDebugTabTest {
|
||||
|
||||
@Test
|
||||
public void resourceEntitySet() throws Exception {
|
||||
EdmEntitySet edmEntitySet = mock(EdmEntitySet.class);
|
||||
final DebugTabUri tab = new DebugTabUri(new UriInfoImpl().setKind(UriInfoKind.resource)
|
||||
.addResourcePart(new UriResourceEntitySetImpl(edmEntitySet)));
|
||||
|
||||
assertEquals("{\"kind\":\"resource\",\"uriResourceParts\":["
|
||||
+ "{\"uriResourceKind\":\"entitySet\",\"segment\":null,\"isCollection\":true}]}",
|
||||
createJson(tab));
|
||||
|
||||
final String html = createHtml(tab);
|
||||
assertThat(html, allOf(
|
||||
startsWith("<h2>Resource Path</h2>\n"
|
||||
+ "<ul>\n"
|
||||
+ "<li class=\"json\">"),
|
||||
containsString("uriResourceKind"), containsString("entitySet"),
|
||||
containsString("segment"), containsString("null")));
|
||||
assertThat(html, allOf(
|
||||
containsString("isCollection"), containsString("true"),
|
||||
endsWith("</li>\n</ul>\n")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resourceFunction() throws Exception {
|
||||
EdmReturnType returnType = mock(EdmReturnType.class);
|
||||
EdmFunction edmFunction = mock(EdmFunction.class);
|
||||
when(edmFunction.getReturnType()).thenReturn(returnType);
|
||||
EdmFunctionImport edmFunctionImport = mock(EdmFunctionImport.class);
|
||||
final DebugTabUri tab = new DebugTabUri(new UriInfoImpl().setKind(UriInfoKind.resource)
|
||||
.addResourcePart(new UriResourceFunctionImpl(edmFunctionImport, edmFunction,
|
||||
Arrays.asList((UriParameter) new UriParameterImpl().setName("parameter1")))));
|
||||
|
||||
assertEquals("{\"kind\":\"resource\",\"uriResourceParts\":["
|
||||
+ "{\"uriResourceKind\":\"function\",\"segment\":null,\"isCollection\":false,"
|
||||
+ "\"parameters\":{\"parameter1\":null}}]}",
|
||||
createJson(tab));
|
||||
|
||||
final String html = createHtml(tab);
|
||||
assertThat(html, allOf(
|
||||
startsWith("<h2>Resource Path</h2>\n"
|
||||
+ "<ul>\n"
|
||||
+ "<li class=\"json\">"),
|
||||
containsString("uriResourceKind"), containsString("function"),
|
||||
containsString("segment"), containsString("null")));
|
||||
assertThat(html, allOf(
|
||||
containsString("isCollection"), containsString("false"),
|
||||
containsString("parameters"), containsString("parameter1"),
|
||||
endsWith("</li>\n</ul>\n")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void crossjoin() throws Exception {
|
||||
final DebugTabUri tab = new DebugTabUri(new UriInfoImpl().setKind(UriInfoKind.crossjoin)
|
||||
.addEntitySetName("ES1").addEntitySetName("ES2"));
|
||||
|
||||
assertEquals("{\"kind\":\"crossjoin\",\"entitySetNames\":[\"ES1\",\"ES2\"]}", createJson(tab));
|
||||
|
||||
assertEquals("<h2>Crossjoin EntitySet Names</h2>\n"
|
||||
+ "<ul>\n"
|
||||
+ "<li>ES1</li>\n"
|
||||
+ "<li>ES2</li>\n"
|
||||
+ "</ul>\n",
|
||||
createHtml(tab));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void entityId() throws Exception {
|
||||
EdmEntityType edmEntityType = mock(EdmEntityType.class);
|
||||
when(edmEntityType.getFullQualifiedName()).thenReturn(new FullQualifiedName("ns", "entityType"));
|
||||
final DebugTabUri tab = new DebugTabUri(new UriInfoImpl().setKind(UriInfoKind.entityId)
|
||||
.setEntityTypeCast(edmEntityType));
|
||||
|
||||
assertEquals("{\"kind\":\"entityId\",\"typeCast\":\"ns.entityType\"}", createJson(tab));
|
||||
|
||||
assertEquals("<h2>Kind</h2>\n"
|
||||
+ "<p>entityId</p>\n"
|
||||
+ "<h2>Type Cast</h2>\n"
|
||||
+ "<p>ns.entityType</p>\n",
|
||||
createHtml(tab));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleQueryOptions() throws Exception {
|
||||
final DebugTabUri tab = new DebugTabUri(new UriInfoImpl().setKind(UriInfoKind.all)
|
||||
.setQueryOption(new FormatOptionImpl().setFormat("json"))
|
||||
.setQueryOption(new IdOptionImpl().setValue("ES(42)").setText("ES(42)"))
|
||||
.setQueryOption(new SkipOptionImpl().setValue(123).setText("123"))
|
||||
.setQueryOption(new TopOptionImpl().setValue(456).setText("456"))
|
||||
.setQueryOption(new SkipTokenOptionImpl().setValue("xyz123"))
|
||||
.setQueryOption(new CountOptionImpl().setValue(false).setText("false"))
|
||||
.setQueryOption(new SearchOptionImpl().setSearchExpression(new SearchTermImpl("searchTest")))
|
||||
.setQueryOption(new CustomQueryOptionImpl().setName("customQuery").setText("customValue"))
|
||||
.setQueryOption(new AliasQueryOptionImpl().setAliasValue(null).setName("@alias")));
|
||||
|
||||
assertEquals("{\"kind\":\"all\","
|
||||
+ "\"format\":\"json\","
|
||||
+ "\"id\":\"ES(42)\","
|
||||
+ "\"skiptoken\":\"xyz123\","
|
||||
+ "\"isCount\":false,"
|
||||
+ "\"skip\":123,"
|
||||
+ "\"top\":456,"
|
||||
+ "\"search\":{\"nodeType\":\"searchTerm\",\"searchTerm\":\"searchTest\"},"
|
||||
+ "\"aliases\":{\"@alias\":null},"
|
||||
+ "\"customQueryOptions\":{\"customQuery\":\"customValue\"}"
|
||||
+ "}",
|
||||
createJson(tab));
|
||||
|
||||
final String html = createHtml(tab);
|
||||
assertThat(html, allOf(
|
||||
startsWith("<h2>Kind</h2>\n"
|
||||
+ "<p>all</p>\n"),
|
||||
containsString("<h2>Search Option</h2>\n"
|
||||
+ "<ul>\n"
|
||||
+ "<li class=\"json\">"),
|
||||
containsString("searchTerm"), containsString("searchTest"),
|
||||
containsString("<h2>Unstructured System Query Options</h2>\n"
|
||||
+ "<table>\n"
|
||||
+ "<thead>\n"
|
||||
+ "<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n"
|
||||
+ "</thead>\n"
|
||||
+ "<tbody>\n"
|
||||
+ "<tr><td class=\"name\">$count</td><td class=\"value\">false</td></tr>\n"
|
||||
+ "<tr><td class=\"name\">$skip</td><td class=\"value\">123</td></tr>\n"
|
||||
+ "<tr><td class=\"name\">$skiptoken</td><td class=\"value\">xyz123</td></tr>\n"
|
||||
+ "<tr><td class=\"name\">$top</td><td class=\"value\">456</td></tr>\n"
|
||||
+ "<tr><td class=\"name\">$format</td><td class=\"value\">json</td></tr>\n"
|
||||
+ "<tr><td class=\"name\">$id</td><td class=\"value\">ES(42)</td></tr>\n"
|
||||
+ "</tbody>\n"
|
||||
+ "</table>\n")));
|
||||
assertThat(html, allOf(
|
||||
containsString("<h2>Aliases</h2>\n"
|
||||
+ "<table>\n"
|
||||
+ "<thead>\n"
|
||||
+ "<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n"
|
||||
+ "</thead>\n"
|
||||
+ "<tbody>\n"
|
||||
+ "<tr><td class=\"name\">@alias</td><td class=\"value\">null</td></tr>\n"
|
||||
+ "</tbody>\n"
|
||||
+ "</table>\n"),
|
||||
endsWith("<h2>Custom Query Options</h2>\n"
|
||||
+ "<table>\n"
|
||||
+ "<thead>\n"
|
||||
+ "<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n"
|
||||
+ "</thead>\n"
|
||||
+ "<tbody>\n"
|
||||
+ "<tr><td class=\"name\">customQuery</td><td class=\"value\">customValue</td></tr>\n"
|
||||
+ "</tbody>\n"
|
||||
+ "</table>\n")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void select() throws Exception {
|
||||
EdmProperty edmProperty = mock(EdmProperty.class);
|
||||
when(edmProperty.getName()).thenReturn("property");
|
||||
final DebugTabUri tab = new DebugTabUri(new UriInfoImpl().setKind(UriInfoKind.all)
|
||||
.setSystemQueryOption(new SelectOptionImpl().setSelectItems(Arrays.asList(
|
||||
(SelectItem) new SelectItemImpl().setStar(true),
|
||||
new SelectItemImpl().setResourcePath(
|
||||
new UriInfoImpl().setKind(UriInfoKind.resource)
|
||||
.addResourcePart(new UriResourcePrimitivePropertyImpl(edmProperty)))))));
|
||||
assertEquals("{\"kind\":\"all\",\"select\":[\"*\",\"property\"]}", createJson(tab));
|
||||
|
||||
assertEquals("<h2>Kind</h2>\n"
|
||||
+ "<p>all</p>\n"
|
||||
+ "<h2>Selected Properties</h2>\n"
|
||||
+ "<ul>\n"
|
||||
+ "<li>*</li>\n"
|
||||
+ "<li>property</li>\n"
|
||||
+ "</ul>\n",
|
||||
createHtml(tab));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expand() throws Exception {
|
||||
EdmNavigationProperty edmProperty = mock(EdmNavigationProperty.class);
|
||||
when(edmProperty.getName()).thenReturn("property");
|
||||
final DebugTabUri tab = new DebugTabUri(new UriInfoImpl().setKind(UriInfoKind.all)
|
||||
.setSystemQueryOption(new ExpandOptionImpl().addExpandItem(
|
||||
new ExpandItemImpl().setResourcePath(
|
||||
new UriInfoImpl().setKind(UriInfoKind.resource)
|
||||
.addResourcePart(new UriResourceNavigationPropertyImpl(edmProperty)))
|
||||
.setSystemQueryOption(new LevelsOptionImpl().setValue(1)))));
|
||||
assertEquals("{\"kind\":\"all\",\"expand\":[{\"expandPath\":["
|
||||
+ "{\"uriResourceKind\":\"navigationProperty\",\"segment\":\"property\",\"isCollection\":false}],"
|
||||
+ "\"levels\":1}]}",
|
||||
createJson(tab));
|
||||
|
||||
final String html = createHtml(tab);
|
||||
assertThat(html, allOf(
|
||||
startsWith("<h2>Kind</h2>\n"
|
||||
+ "<p>all</p>\n"
|
||||
+ "<h2>Expand Option</h2>\n"
|
||||
+ "<ul>\n"
|
||||
+ "<li class=\"json\">"),
|
||||
containsString("navigationProperty"), containsString("property"),
|
||||
containsString("isCollection"), containsString("false")));
|
||||
assertThat(html, allOf(containsString("levels"), endsWith("</li>\n</ul>\n")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filter() throws Exception {
|
||||
final DebugTabUri tab = new DebugTabUri(new UriInfoImpl().setKind(UriInfoKind.all)
|
||||
.setSystemQueryOption(new FilterOptionImpl().setExpression(
|
||||
new BinaryImpl(new LiteralImpl("1", EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Int64)),
|
||||
BinaryOperatorKind.GT,
|
||||
new LiteralImpl("2", EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.SByte)),
|
||||
EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean)))));
|
||||
assertEquals("{\"kind\":\"all\",\"filter\":{"
|
||||
+ "\"nodeType\":\"binary\",\"operator\":\"gt\",\"type\":\"Boolean\","
|
||||
+ "\"left\":{\"nodeType\":\"literal\",\"type\":\"Edm.Int64\",\"value\":\"1\"},"
|
||||
+ "\"right\":{\"nodeType\":\"literal\",\"type\":\"Edm.SByte\",\"value\":\"2\"}}}",
|
||||
createJson(tab));
|
||||
|
||||
assertThat(createHtml(tab), allOf(
|
||||
startsWith("<h2>Kind</h2>\n"
|
||||
+ "<p>all</p>\n"
|
||||
+ "<h2>Filter Option</h2>\n"
|
||||
+ "<ul>\n"
|
||||
+ "<li class=\"json\">"),
|
||||
containsString("nodeType"), containsString("binary"),
|
||||
containsString("operator"), containsString("gt")));
|
||||
assertThat(createHtml(tab), allOf(
|
||||
containsString("literal"), containsString("Int64"),
|
||||
containsString("SByte"), containsString("2"),
|
||||
endsWith("</li>\n</ul>\n")));
|
||||
|
||||
assertEquals("{\"kind\":\"all\",\"filter\":{"
|
||||
+ "\"nodeType\":\"method\",\"operator\":\"ceiling\",\"type\":\"Number\","
|
||||
+ "\"parameters\":[{\"nodeType\":\"literal\",\"type\":\"Edm.Decimal\",\"value\":\"1.5\"}]}}",
|
||||
createJson(new DebugTabUri(new UriInfoImpl().setKind(UriInfoKind.all)
|
||||
.setSystemQueryOption(new FilterOptionImpl().setExpression(
|
||||
new MethodImpl(MethodKind.CEILING, Arrays.asList(
|
||||
(Expression) new LiteralImpl("1.5",
|
||||
EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Decimal)))))))));
|
||||
|
||||
EdmEntityType edmEntityType = mock(EdmEntityType.class);
|
||||
when(edmEntityType.getFullQualifiedName()).thenReturn(new FullQualifiedName("ns", "entityType"));
|
||||
EdmProperty edmProperty = mock(EdmProperty.class);
|
||||
when(edmProperty.getName()).thenReturn("property");
|
||||
assertEquals("{\"kind\":\"all\",\"filter\":{"
|
||||
+ "\"nodeType\":\"member\",\"type\":\"unknown\",\"typeFilter\":\"ns.entityType\","
|
||||
+ "\"resourceSegments\":[{\"nodeType\":\"primitiveProperty\",\"name\":\"property\",\"type\":\"unknown\"}]}}",
|
||||
createJson(new DebugTabUri(new UriInfoImpl().setKind(UriInfoKind.all)
|
||||
.setSystemQueryOption(new FilterOptionImpl().setExpression(
|
||||
new MemberImpl(new UriInfoImpl().setKind(UriInfoKind.resource)
|
||||
.addResourcePart(new UriResourcePrimitivePropertyImpl(edmProperty)),
|
||||
edmEntityType))))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void orderby() throws Exception {
|
||||
final DebugTabUri tab = new DebugTabUri(new UriInfoImpl().setKind(UriInfoKind.all)
|
||||
.setSystemQueryOption(new OrderByOptionImpl().addOrder(
|
||||
new OrderByItemImpl().setExpression(
|
||||
new LiteralImpl("false", EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean)))
|
||||
.setDescending(true))));
|
||||
|
||||
assertEquals("{\"kind\":\"all\",\"orderby\":{\"nodeType\":\"orderCollection\",\"orders\":["
|
||||
+ "{\"nodeType\":\"order\",\"sortorder\":\"desc\",\"expression\":"
|
||||
+ "{\"nodeType\":\"literal\",\"type\":\"Edm.Boolean\",\"value\":\"false\"}}]}}",
|
||||
createJson(tab));
|
||||
|
||||
final String html = createHtml(tab);
|
||||
assertThat(html, allOf(
|
||||
startsWith("<h2>Kind</h2>\n"
|
||||
+ "<p>all</p>\n"
|
||||
+ "<h2>OrderBy Option</h2>\n"
|
||||
+ "<ul>\n"
|
||||
+ "<li class=\"json\">"),
|
||||
containsString("nodeType"), containsString("order"),
|
||||
containsString("sortorder"), containsString("desc")));
|
||||
assertThat(html, allOf(
|
||||
containsString("expression"), containsString("literal"),
|
||||
containsString("Edm.Boolean"), containsString("false"),
|
||||
endsWith("</li>\n</ul>\n")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void apply() throws Exception {
|
||||
EdmProperty edmProperty = mock(EdmProperty.class);
|
||||
when(edmProperty.getName()).thenReturn("property");
|
||||
final DebugTabUri tab = new DebugTabUri(new UriInfoImpl().setKind(UriInfoKind.all)
|
||||
.setSystemQueryOption(new ApplyOptionImpl().add(new AggregateImpl().addExpression(
|
||||
new AggregateExpressionImpl()
|
||||
.setPath(new UriInfoImpl().setKind(UriInfoKind.resource).addResourcePart(
|
||||
new UriResourcePrimitivePropertyImpl(edmProperty)))
|
||||
.setStandardMethod(StandardMethod.AVERAGE)
|
||||
.setAlias("average")))));
|
||||
|
||||
assertEquals("{\"kind\":\"all\",\"apply\":[{\"kind\":\"AGGREGATE\",\"aggregate\":[{"
|
||||
+ "\"path\":[{\"uriResourceKind\":\"primitiveProperty\",\"segment\":\"property\",\"isCollection\":false}],"
|
||||
+ "\"standardMethod\":\"AVERAGE\",\"as\":\"average\"}]}]}",
|
||||
createJson(tab));
|
||||
|
||||
final String html = createHtml(tab);
|
||||
assertThat(html, allOf(
|
||||
startsWith("<h2>Kind</h2>\n"
|
||||
+ "<p>all</p>\n"
|
||||
+ "<h2>Apply Option</h2>\n"
|
||||
+ "<ul>\n"
|
||||
+ "<li class=\"json\">"),
|
||||
containsString("kind"), containsString("AGGREGATE"),
|
||||
containsString("aggregate"), containsString("path")));
|
||||
assertThat(html, allOf(
|
||||
containsString("primitiveProperty"), containsString("property"),
|
||||
containsString("standardMethod"), containsString("AVERAGE")));
|
||||
assertThat(html, allOf(
|
||||
containsString("as"), containsString("average"),
|
||||
endsWith("</li>\n</ul>\n")));
|
||||
|
||||
assertEquals("{\"kind\":\"all\",\"apply\":[{\"kind\":\"GROUP_BY\",\"groupBy\":[{"
|
||||
+ "\"path\":[{\"uriResourceKind\":\"primitiveProperty\",\"segment\":\"property\",\"isCollection\":false}],"
|
||||
+ "\"isRollupAll\":true}]}]}",
|
||||
createJson(new DebugTabUri(new UriInfoImpl().setKind(UriInfoKind.all)
|
||||
.setSystemQueryOption(new ApplyOptionImpl().add(new GroupByImpl().addGroupByItem(
|
||||
new GroupByItemImpl().setIsRollupAll()
|
||||
.setPath(new UriInfoImpl().setKind(UriInfoKind.resource).addResourcePart(
|
||||
new UriResourcePrimitivePropertyImpl(edmProperty)))))))));
|
||||
}
|
||||
}
|
|
@ -18,8 +18,11 @@
|
|||
*/
|
||||
package org.apache.olingo.server.core.debug;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.allOf;
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
@ -36,20 +39,22 @@ import org.apache.olingo.server.api.OData;
|
|||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.debug.DebugInformation;
|
||||
import org.apache.olingo.server.api.debug.DebugSupport;
|
||||
import org.apache.olingo.server.api.debug.DefaultDebugSupport;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ServerCoreDebuggerTest {
|
||||
|
||||
private final OData odata = OData.newInstance();
|
||||
private ServerCoreDebugger debugger;
|
||||
|
||||
@Before
|
||||
public void setupDebugger() {
|
||||
debugger = new ServerCoreDebugger(OData.newInstance());
|
||||
debugger = new ServerCoreDebugger(odata);
|
||||
DebugSupport processor = mock(DebugSupport.class);
|
||||
when(processor.isUserAuthorized()).thenReturn(true);
|
||||
when(processor.createDebugResponse(anyString(), any(DebugInformation.class)))
|
||||
.thenThrow(new ODataRuntimeException("Test"));
|
||||
.thenThrow(new ODataRuntimeException("Test"));
|
||||
debugger.setDebugSupportProcessor(processor);
|
||||
}
|
||||
|
||||
|
@ -63,7 +68,7 @@ public class ServerCoreDebuggerTest {
|
|||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
when(request.getParameter(DebugSupport.ODATA_DEBUG_QUERY_PARAMETER)).thenReturn(DebugSupport.ODATA_DEBUG_JSON);
|
||||
|
||||
ServerCoreDebugger localDebugger = new ServerCoreDebugger(OData.newInstance());
|
||||
ServerCoreDebugger localDebugger = new ServerCoreDebugger(odata);
|
||||
localDebugger.resolveDebugMode(request);
|
||||
assertFalse(debugger.isDebugMode());
|
||||
}
|
||||
|
@ -84,7 +89,7 @@ public class ServerCoreDebuggerTest {
|
|||
DebugSupport debugSupportMock = mock(DebugSupport.class);
|
||||
when(debugSupportMock.isUserAuthorized()).thenReturn(false);
|
||||
|
||||
ServerCoreDebugger localDebugger = new ServerCoreDebugger(OData.newInstance());
|
||||
ServerCoreDebugger localDebugger = new ServerCoreDebugger(odata);
|
||||
localDebugger.setDebugSupportProcessor(debugSupportMock);
|
||||
|
||||
localDebugger.resolveDebugMode(request);
|
||||
|
@ -108,4 +113,28 @@ public class ServerCoreDebuggerTest {
|
|||
|
||||
assertEquals(odResponse, debugResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runtimeMeasurement() throws Exception {
|
||||
ServerCoreDebugger defaultDebugger = new ServerCoreDebugger(odata);
|
||||
defaultDebugger.setDebugSupportProcessor(new DefaultDebugSupport());
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
when(request.getParameter(DebugSupport.ODATA_DEBUG_QUERY_PARAMETER)).thenReturn(DebugSupport.ODATA_DEBUG_JSON);
|
||||
defaultDebugger.resolveDebugMode(request);
|
||||
|
||||
final int handle = defaultDebugger.startRuntimeMeasurement("someClass", "someMethod");
|
||||
defaultDebugger.stopRuntimeMeasurement(handle);
|
||||
assertEquals(0, handle);
|
||||
|
||||
assertThat(IOUtils.toString(defaultDebugger.createDebugResponse(null, null, null, null, null).getContent()),
|
||||
allOf(containsString("\"runtime\""), containsString("\"someClass\""), containsString("\"someMethod\""),
|
||||
containsString("]}}")));
|
||||
|
||||
request = mock(HttpServletRequest.class);
|
||||
when(request.getParameter(DebugSupport.ODATA_DEBUG_QUERY_PARAMETER)).thenReturn(DebugSupport.ODATA_DEBUG_HTML);
|
||||
defaultDebugger.resolveDebugMode(request);
|
||||
assertThat(IOUtils.toString(defaultDebugger.createDebugResponse(null, null, null, null, null).getContent()),
|
||||
allOf(containsString(">Runtime<"), containsString(">someClass<"), containsString(">someMethod("),
|
||||
containsString("</html>")));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue