Convert jsp 2.3 tests from groovy to java (#11827)
This commit is contained in:
parent
14d87e7323
commit
e7a6398c71
|
@ -1,539 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
||||
import io.opentelemetry.instrumentation.test.utils.PortUtils
|
||||
import io.opentelemetry.semconv.ExceptionAttributes
|
||||
import io.opentelemetry.semconv.ServerAttributes
|
||||
import io.opentelemetry.semconv.ClientAttributes
|
||||
import io.opentelemetry.semconv.UserAgentAttributes
|
||||
import io.opentelemetry.semconv.ErrorAttributes
|
||||
import io.opentelemetry.semconv.HttpAttributes
|
||||
import io.opentelemetry.semconv.NetworkAttributes
|
||||
import io.opentelemetry.semconv.UrlAttributes
|
||||
import io.opentelemetry.testing.internal.armeria.client.WebClient
|
||||
import io.opentelemetry.testing.internal.armeria.common.AggregatedHttpResponse
|
||||
import io.opentelemetry.testing.internal.armeria.common.HttpMethod
|
||||
import io.opentelemetry.testing.internal.armeria.common.MediaType
|
||||
import io.opentelemetry.testing.internal.armeria.common.RequestHeaders
|
||||
import org.apache.catalina.Context
|
||||
import org.apache.catalina.startup.Tomcat
|
||||
import org.apache.jasper.JasperException
|
||||
import spock.lang.Shared
|
||||
import spock.lang.Unroll
|
||||
|
||||
import java.nio.file.Files
|
||||
|
||||
import static io.opentelemetry.api.trace.SpanKind.SERVER
|
||||
import static io.opentelemetry.api.trace.StatusCode.ERROR
|
||||
|
||||
//TODO should this be HttpServerTest?
|
||||
class JspInstrumentationBasicTests extends AgentInstrumentationSpecification {
|
||||
|
||||
@Shared
|
||||
int port
|
||||
@Shared
|
||||
Tomcat tomcatServer
|
||||
@Shared
|
||||
Context appContext
|
||||
@Shared
|
||||
String jspWebappContext = "jsptest-context"
|
||||
|
||||
@Shared
|
||||
File baseDir
|
||||
@Shared
|
||||
String baseUrl
|
||||
|
||||
@Shared
|
||||
WebClient client
|
||||
|
||||
def setupSpec() {
|
||||
baseDir = Files.createTempDirectory("jsp").toFile()
|
||||
baseDir.deleteOnExit()
|
||||
|
||||
port = PortUtils.findOpenPort()
|
||||
|
||||
tomcatServer = new Tomcat()
|
||||
tomcatServer.setBaseDir(baseDir.getAbsolutePath())
|
||||
tomcatServer.setPort(port)
|
||||
tomcatServer.getConnector()
|
||||
// comment to debug
|
||||
tomcatServer.setSilent(true)
|
||||
// this is needed in tomcat 9, this triggers the creation of a connector, will not
|
||||
// affect tomcat 7 and 8
|
||||
// https://stackoverflow.com/questions/48998387/code-works-with-embedded-apache-tomcat-8-but-not-with-9-whats-changed
|
||||
tomcatServer.getConnector()
|
||||
baseUrl = "http://localhost:$port/$jspWebappContext"
|
||||
client = WebClient.of(baseUrl)
|
||||
|
||||
appContext = tomcatServer.addWebapp("/$jspWebappContext",
|
||||
JspInstrumentationBasicTests.getResource("/webapps/jsptest").getPath())
|
||||
|
||||
tomcatServer.start()
|
||||
System.out.println(
|
||||
"Tomcat server: http://" + tomcatServer.getHost().getName() + ":" + port + "/")
|
||||
}
|
||||
|
||||
def cleanupSpec() {
|
||||
tomcatServer.stop()
|
||||
tomcatServer.destroy()
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "non-erroneous GET #test test"() {
|
||||
when:
|
||||
AggregatedHttpResponse res = client.get("/${jspFileName}").aggregate().join()
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 3) {
|
||||
span(0) {
|
||||
def route = "/$jspWebappContext/$jspFileName"
|
||||
|
||||
hasNoParent()
|
||||
name "GET $route"
|
||||
kind SERVER
|
||||
attributes {
|
||||
"$UrlAttributes.URL_SCHEME" "http"
|
||||
"$UrlAttributes.URL_PATH" route
|
||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "GET"
|
||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200
|
||||
"$UserAgentAttributes.USER_AGENT_ORIGINAL" String
|
||||
"$HttpAttributes.HTTP_ROUTE" route
|
||||
"$NetworkAttributes.NETWORK_PROTOCOL_VERSION" "1.1"
|
||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
||||
"$ServerAttributes.SERVER_PORT" port
|
||||
"$ClientAttributes.CLIENT_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_PORT" Long
|
||||
}
|
||||
}
|
||||
span(1) {
|
||||
childOf span(0)
|
||||
name "Compile /$jspFileName"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.$jspClassNamePrefix$jspClassName"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(2) {
|
||||
childOf span(0)
|
||||
name "Render /$jspFileName"
|
||||
attributes {
|
||||
"jsp.requestURL" "${baseUrl}/${jspFileName}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res.status().code() == 200
|
||||
|
||||
where:
|
||||
test | jspFileName | jspClassName | jspClassNamePrefix
|
||||
"no java jsp" | "nojava.jsp" | "nojava_jsp" | ""
|
||||
"basic loop jsp" | "common/loop.jsp" | "loop_jsp" | "common."
|
||||
"invalid HTML markup" | "invalidMarkup.jsp" | "invalidMarkup_jsp" | ""
|
||||
}
|
||||
|
||||
def "non-erroneous GET with query string"() {
|
||||
setup:
|
||||
String queryString = "HELLO"
|
||||
|
||||
when:
|
||||
AggregatedHttpResponse res = client.get("/getQuery.jsp?${queryString}").aggregate().join()
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 3) {
|
||||
span(0) {
|
||||
def route = "/$jspWebappContext/getQuery.jsp"
|
||||
|
||||
hasNoParent()
|
||||
name "GET $route"
|
||||
kind SERVER
|
||||
attributes {
|
||||
"$UrlAttributes.URL_SCHEME" "http"
|
||||
"$UrlAttributes.URL_PATH" route
|
||||
"$UrlAttributes.URL_QUERY" queryString
|
||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "GET"
|
||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200
|
||||
"$UserAgentAttributes.USER_AGENT_ORIGINAL" String
|
||||
"$HttpAttributes.HTTP_ROUTE" route
|
||||
"$NetworkAttributes.NETWORK_PROTOCOL_VERSION" "1.1"
|
||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
||||
"$ServerAttributes.SERVER_PORT" port
|
||||
"$ClientAttributes.CLIENT_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_PORT" Long
|
||||
}
|
||||
}
|
||||
span(1) {
|
||||
childOf span(0)
|
||||
name "Compile /getQuery.jsp"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.getQuery_jsp"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(2) {
|
||||
childOf span(0)
|
||||
name "Render /getQuery.jsp"
|
||||
attributes {
|
||||
"jsp.requestURL" "${baseUrl}/getQuery.jsp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res.status().code() == 200
|
||||
}
|
||||
|
||||
def "non-erroneous POST"() {
|
||||
setup:
|
||||
RequestHeaders headers = RequestHeaders.builder(HttpMethod.POST, "/post.jsp")
|
||||
.contentType(MediaType.FORM_DATA)
|
||||
.build()
|
||||
|
||||
when:
|
||||
AggregatedHttpResponse res = client.execute(headers, "name=world").aggregate().join()
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 3) {
|
||||
span(0) {
|
||||
def route = "/$jspWebappContext/post.jsp"
|
||||
|
||||
hasNoParent()
|
||||
name "POST $route"
|
||||
kind SERVER
|
||||
attributes {
|
||||
"$UrlAttributes.URL_SCHEME" "http"
|
||||
"$UrlAttributes.URL_PATH" route
|
||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "POST"
|
||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200
|
||||
"$UserAgentAttributes.USER_AGENT_ORIGINAL" String
|
||||
"$HttpAttributes.HTTP_ROUTE" route
|
||||
"$NetworkAttributes.NETWORK_PROTOCOL_VERSION" "1.1"
|
||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
||||
"$ServerAttributes.SERVER_PORT" port
|
||||
"$ClientAttributes.CLIENT_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1"
|
||||
|
||||
"$NetworkAttributes.NETWORK_PEER_PORT" Long
|
||||
}
|
||||
}
|
||||
span(1) {
|
||||
childOf span(0)
|
||||
name "Compile /post.jsp"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.post_jsp"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(2) {
|
||||
childOf span(0)
|
||||
name "Render /post.jsp"
|
||||
attributes {
|
||||
"jsp.requestURL" "${baseUrl}/post.jsp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res.status().code() == 200
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "erroneous runtime errors GET jsp with #test test"() {
|
||||
when:
|
||||
AggregatedHttpResponse res = client.get("/${jspFileName}").aggregate().join()
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 3) {
|
||||
span(0) {
|
||||
def route = "/$jspWebappContext/$jspFileName"
|
||||
|
||||
hasNoParent()
|
||||
name "GET $route"
|
||||
kind SERVER
|
||||
status ERROR
|
||||
event(0) {
|
||||
eventName("exception")
|
||||
attributes {
|
||||
"$ExceptionAttributes.EXCEPTION_TYPE" { String tagExceptionType ->
|
||||
return tagExceptionType == exceptionClass.getName() || tagExceptionType.contains(exceptionClass.getSimpleName())
|
||||
}
|
||||
"$ExceptionAttributes.EXCEPTION_MESSAGE" { String tagErrorMsg ->
|
||||
return errorMessageOptional || tagErrorMsg instanceof String
|
||||
}
|
||||
"$ExceptionAttributes.EXCEPTION_STACKTRACE" String
|
||||
}
|
||||
}
|
||||
attributes {
|
||||
"$UrlAttributes.URL_SCHEME" "http"
|
||||
"$UrlAttributes.URL_PATH" route
|
||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "GET"
|
||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 500
|
||||
"$UserAgentAttributes.USER_AGENT_ORIGINAL" String
|
||||
"$HttpAttributes.HTTP_ROUTE" route
|
||||
"$NetworkAttributes.NETWORK_PROTOCOL_VERSION" "1.1"
|
||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
||||
"$ServerAttributes.SERVER_PORT" port
|
||||
"$ClientAttributes.CLIENT_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_PORT" Long
|
||||
"$ErrorAttributes.ERROR_TYPE" "500"
|
||||
}
|
||||
}
|
||||
span(1) {
|
||||
childOf span(0)
|
||||
name "Compile /$jspFileName"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.$jspClassName"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(2) {
|
||||
childOf span(0)
|
||||
name "Render /$jspFileName"
|
||||
status ERROR
|
||||
event(0) {
|
||||
eventName("exception")
|
||||
attributes {
|
||||
"$ExceptionAttributes.EXCEPTION_TYPE" { String tagExceptionType ->
|
||||
return tagExceptionType == exceptionClass.getName() || tagExceptionType.contains(exceptionClass.getSimpleName())
|
||||
}
|
||||
"$ExceptionAttributes.EXCEPTION_MESSAGE" { String tagErrorMsg ->
|
||||
return errorMessageOptional || tagErrorMsg instanceof String
|
||||
}
|
||||
"$ExceptionAttributes.EXCEPTION_STACKTRACE" String
|
||||
}
|
||||
}
|
||||
attributes {
|
||||
"jsp.requestURL" "${baseUrl}/${jspFileName}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res.status().code() == 500
|
||||
|
||||
where:
|
||||
test | jspFileName | jspClassName | exceptionClass | errorMessageOptional
|
||||
"java runtime error" | "runtimeError.jsp" | "runtimeError_jsp" | ArithmeticException | false
|
||||
"invalid write" | "invalidWrite.jsp" | "invalidWrite_jsp" | IndexOutOfBoundsException | true
|
||||
"missing query gives null" | "getQuery.jsp" | "getQuery_jsp" | NullPointerException | true
|
||||
}
|
||||
|
||||
def "non-erroneous include plain HTML GET"() {
|
||||
when:
|
||||
AggregatedHttpResponse res = client.get("/includes/includeHtml.jsp").aggregate().join()
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 3) {
|
||||
span(0) {
|
||||
def route = "/$jspWebappContext/includes/includeHtml.jsp"
|
||||
|
||||
hasNoParent()
|
||||
name "GET $route"
|
||||
kind SERVER
|
||||
attributes {
|
||||
"$UrlAttributes.URL_SCHEME" "http"
|
||||
"$UrlAttributes.URL_PATH" route
|
||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "GET"
|
||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200
|
||||
"$UserAgentAttributes.USER_AGENT_ORIGINAL" String
|
||||
"$HttpAttributes.HTTP_ROUTE" route
|
||||
"$NetworkAttributes.NETWORK_PROTOCOL_VERSION" "1.1"
|
||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
||||
"$ServerAttributes.SERVER_PORT" port
|
||||
"$ClientAttributes.CLIENT_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_PORT" Long
|
||||
}
|
||||
}
|
||||
span(1) {
|
||||
childOf span(0)
|
||||
name "Compile /includes/includeHtml.jsp"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.includes.includeHtml_jsp"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(2) {
|
||||
childOf span(0)
|
||||
name "Render /includes/includeHtml.jsp"
|
||||
attributes {
|
||||
"jsp.requestURL" "${baseUrl}/includes/includeHtml.jsp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res.status().code() == 200
|
||||
}
|
||||
|
||||
def "non-erroneous multi GET"() {
|
||||
when:
|
||||
AggregatedHttpResponse res = client.get("/includes/includeMulti.jsp").aggregate().join()
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 7) {
|
||||
span(0) {
|
||||
def route = "/$jspWebappContext/includes/includeMulti.jsp"
|
||||
|
||||
hasNoParent()
|
||||
name "GET $route"
|
||||
kind SERVER
|
||||
attributes {
|
||||
"$UrlAttributes.URL_SCHEME" "http"
|
||||
"$UrlAttributes.URL_PATH" route
|
||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "GET"
|
||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200
|
||||
"$UserAgentAttributes.USER_AGENT_ORIGINAL" String
|
||||
"$HttpAttributes.HTTP_ROUTE" route
|
||||
"$NetworkAttributes.NETWORK_PROTOCOL_VERSION" "1.1"
|
||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
||||
"$ServerAttributes.SERVER_PORT" port
|
||||
"$ClientAttributes.CLIENT_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_PORT" Long
|
||||
}
|
||||
}
|
||||
span(1) {
|
||||
childOf span(0)
|
||||
name "Compile /includes/includeMulti.jsp"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.includes.includeMulti_jsp"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(2) {
|
||||
childOf span(0)
|
||||
name "Render /includes/includeMulti.jsp"
|
||||
attributes {
|
||||
"jsp.requestURL" "${baseUrl}/includes/includeMulti.jsp"
|
||||
}
|
||||
}
|
||||
span(3) {
|
||||
childOf span(2)
|
||||
name "Compile /common/javaLoopH2.jsp"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.common.javaLoopH2_jsp"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(4) {
|
||||
childOf span(2)
|
||||
name "Render /common/javaLoopH2.jsp"
|
||||
attributes {
|
||||
"jsp.requestURL" "${baseUrl}/includes/includeMulti.jsp"
|
||||
}
|
||||
}
|
||||
span(5) {
|
||||
childOf span(2)
|
||||
name "Compile /common/javaLoopH2.jsp"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.common.javaLoopH2_jsp"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(6) {
|
||||
childOf span(2)
|
||||
name "Render /common/javaLoopH2.jsp"
|
||||
attributes {
|
||||
"jsp.requestURL" "${baseUrl}/includes/includeMulti.jsp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res.status().code() == 200
|
||||
}
|
||||
|
||||
def "#test compile error should not produce render traces and spans"() {
|
||||
when:
|
||||
AggregatedHttpResponse res = client.get("/${jspFileName}").aggregate().join()
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 2) {
|
||||
span(0) {
|
||||
def route = "/$jspWebappContext/$jspFileName"
|
||||
|
||||
hasNoParent()
|
||||
name "GET $route"
|
||||
kind SERVER
|
||||
status ERROR
|
||||
errorEvent(JasperException, String)
|
||||
attributes {
|
||||
"$UrlAttributes.URL_SCHEME" "http"
|
||||
"$UrlAttributes.URL_PATH" route
|
||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "GET"
|
||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 500
|
||||
"$UserAgentAttributes.USER_AGENT_ORIGINAL" String
|
||||
"$HttpAttributes.HTTP_ROUTE" route
|
||||
"$NetworkAttributes.NETWORK_PROTOCOL_VERSION" "1.1"
|
||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
||||
"$ServerAttributes.SERVER_PORT" port
|
||||
"$ClientAttributes.CLIENT_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_PORT" Long
|
||||
"$ErrorAttributes.ERROR_TYPE" "500"
|
||||
}
|
||||
}
|
||||
span(1) {
|
||||
childOf span(0)
|
||||
name "Compile /$jspFileName"
|
||||
status ERROR
|
||||
errorEvent(JasperException, String)
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.$jspClassNamePrefix$jspClassName"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res.status().code() == 500
|
||||
|
||||
where:
|
||||
test | jspFileName | jspClassName | jspClassNamePrefix
|
||||
"normal" | "compileError.jsp" | "compileError_jsp" | ""
|
||||
"forward" | "forwards/forwardWithCompileError.jsp" | "forwardWithCompileError_jsp" | "forwards."
|
||||
}
|
||||
|
||||
def "direct static file reference"() {
|
||||
when:
|
||||
AggregatedHttpResponse res = client.get("/${staticFile}").aggregate().join()
|
||||
|
||||
then:
|
||||
res.status().code() == 200
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
def route = "/$jspWebappContext/*"
|
||||
|
||||
hasNoParent()
|
||||
name "GET $route"
|
||||
kind SERVER
|
||||
attributes {
|
||||
"$UrlAttributes.URL_SCHEME" "http"
|
||||
"$UrlAttributes.URL_PATH" "/$jspWebappContext/$staticFile"
|
||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "GET"
|
||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200
|
||||
"$UserAgentAttributes.USER_AGENT_ORIGINAL" String
|
||||
"$HttpAttributes.HTTP_ROUTE" route
|
||||
"$NetworkAttributes.NETWORK_PROTOCOL_VERSION" "1.1"
|
||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
||||
"$ServerAttributes.SERVER_PORT" port
|
||||
"$ClientAttributes.CLIENT_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_PORT" Long
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
staticFile = "common/hello.html"
|
||||
}
|
||||
}
|
|
@ -1,490 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
||||
import io.opentelemetry.instrumentation.test.utils.PortUtils
|
||||
import io.opentelemetry.semconv.ServerAttributes
|
||||
import io.opentelemetry.semconv.ClientAttributes
|
||||
import io.opentelemetry.semconv.UserAgentAttributes
|
||||
import io.opentelemetry.semconv.ErrorAttributes
|
||||
import io.opentelemetry.semconv.HttpAttributes
|
||||
import io.opentelemetry.semconv.NetworkAttributes
|
||||
import io.opentelemetry.semconv.UrlAttributes
|
||||
import io.opentelemetry.testing.internal.armeria.client.WebClient
|
||||
import io.opentelemetry.testing.internal.armeria.common.AggregatedHttpResponse
|
||||
import org.apache.catalina.Context
|
||||
import org.apache.catalina.startup.Tomcat
|
||||
import org.apache.jasper.JasperException
|
||||
import spock.lang.Shared
|
||||
import spock.lang.Unroll
|
||||
|
||||
import java.nio.file.Files
|
||||
|
||||
import static io.opentelemetry.api.trace.SpanKind.SERVER
|
||||
import static io.opentelemetry.api.trace.StatusCode.ERROR
|
||||
import static io.opentelemetry.api.trace.StatusCode.UNSET
|
||||
|
||||
class JspInstrumentationForwardTests extends AgentInstrumentationSpecification {
|
||||
|
||||
@Shared
|
||||
int port
|
||||
@Shared
|
||||
Tomcat tomcatServer
|
||||
@Shared
|
||||
Context appContext
|
||||
@Shared
|
||||
String jspWebappContext = "jsptest-context"
|
||||
|
||||
@Shared
|
||||
File baseDir
|
||||
@Shared
|
||||
String baseUrl
|
||||
|
||||
@Shared
|
||||
WebClient client
|
||||
|
||||
def setupSpec() {
|
||||
baseDir = Files.createTempDirectory("jsp").toFile()
|
||||
baseDir.deleteOnExit()
|
||||
|
||||
port = PortUtils.findOpenPort()
|
||||
|
||||
tomcatServer = new Tomcat()
|
||||
tomcatServer.setBaseDir(baseDir.getAbsolutePath())
|
||||
tomcatServer.setPort(port)
|
||||
tomcatServer.getConnector()
|
||||
// comment to debug
|
||||
tomcatServer.setSilent(true)
|
||||
// this is needed in tomcat 9, this triggers the creation of a connector, will not
|
||||
// affect tomcat 7 and 8
|
||||
// https://stackoverflow.com/questions/48998387/code-works-with-embedded-apache-tomcat-8-but-not-with-9-whats-changed
|
||||
tomcatServer.getConnector()
|
||||
|
||||
baseUrl = "http://localhost:$port/$jspWebappContext"
|
||||
client = WebClient.of(baseUrl)
|
||||
|
||||
appContext = tomcatServer.addWebapp("/$jspWebappContext",
|
||||
JspInstrumentationForwardTests.getResource("/webapps/jsptest").getPath())
|
||||
|
||||
tomcatServer.start()
|
||||
System.out.println(
|
||||
"Tomcat server: http://" + tomcatServer.getHost().getName() + ":" + port + "/")
|
||||
}
|
||||
|
||||
def cleanupSpec() {
|
||||
tomcatServer.stop()
|
||||
tomcatServer.destroy()
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "non-erroneous GET forward to #forwardTo"() {
|
||||
when:
|
||||
AggregatedHttpResponse res = client.get("/$forwardFromFileName").aggregate().join()
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 5) {
|
||||
span(0) {
|
||||
def route = "/$jspWebappContext/$forwardFromFileName"
|
||||
|
||||
hasNoParent()
|
||||
name "GET $route"
|
||||
kind SERVER
|
||||
attributes {
|
||||
"$UrlAttributes.URL_SCHEME" "http"
|
||||
"$UrlAttributes.URL_PATH" route
|
||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "GET"
|
||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200
|
||||
"$UserAgentAttributes.USER_AGENT_ORIGINAL" String
|
||||
"$HttpAttributes.HTTP_ROUTE" route
|
||||
"$NetworkAttributes.NETWORK_PROTOCOL_VERSION" "1.1"
|
||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
||||
"$ServerAttributes.SERVER_PORT" port
|
||||
"$ClientAttributes.CLIENT_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_PORT" Long
|
||||
}
|
||||
}
|
||||
span(1) {
|
||||
childOf span(0)
|
||||
name "Compile /$forwardFromFileName"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.$jspForwardFromClassPrefix$jspForwardFromClassName"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(2) {
|
||||
childOf span(0)
|
||||
name "Render /$forwardFromFileName"
|
||||
attributes {
|
||||
"jsp.requestURL" "${baseUrl}/$forwardFromFileName"
|
||||
}
|
||||
}
|
||||
span(3) {
|
||||
childOf span(2)
|
||||
name "Compile /$forwardDestFileName"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.$jspForwardDestClassPrefix$jspForwardDestClassName"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(4) {
|
||||
childOf span(2)
|
||||
name "Render /$forwardDestFileName"
|
||||
attributes {
|
||||
"jsp.forwardOrigin" "/$forwardFromFileName"
|
||||
"jsp.requestURL" "${baseUrl}/$forwardDestFileName"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res.status().code() == 200
|
||||
|
||||
where:
|
||||
forwardTo | forwardFromFileName | forwardDestFileName | jspForwardFromClassName | jspForwardFromClassPrefix | jspForwardDestClassName | jspForwardDestClassPrefix
|
||||
"no java jsp" | "forwards/forwardToNoJavaJsp.jsp" | "nojava.jsp" | "forwardToNoJavaJsp_jsp" | "forwards." | "nojava_jsp" | ""
|
||||
"normal java jsp" | "forwards/forwardToSimpleJava.jsp" | "common/loop.jsp" | "forwardToSimpleJava_jsp" | "forwards." | "loop_jsp" | "common."
|
||||
}
|
||||
|
||||
def "non-erroneous GET forward to plain HTML"() {
|
||||
when:
|
||||
AggregatedHttpResponse res = client.get("/forwards/forwardToHtml.jsp").aggregate().join()
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 3) {
|
||||
span(0) {
|
||||
def route = "/$jspWebappContext/forwards/forwardToHtml.jsp"
|
||||
|
||||
hasNoParent()
|
||||
name "GET $route"
|
||||
kind SERVER
|
||||
attributes {
|
||||
"$UrlAttributes.URL_SCHEME" "http"
|
||||
"$UrlAttributes.URL_PATH" route
|
||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "GET"
|
||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200
|
||||
"$UserAgentAttributes.USER_AGENT_ORIGINAL" String
|
||||
"$HttpAttributes.HTTP_ROUTE" route
|
||||
"$NetworkAttributes.NETWORK_PROTOCOL_VERSION" "1.1"
|
||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
||||
"$ServerAttributes.SERVER_PORT" port
|
||||
"$ClientAttributes.CLIENT_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_PORT" Long
|
||||
}
|
||||
}
|
||||
span(1) {
|
||||
childOf span(0)
|
||||
name "Compile /forwards/forwardToHtml.jsp"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.forwards.forwardToHtml_jsp"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(2) {
|
||||
childOf span(0)
|
||||
name "Render /forwards/forwardToHtml.jsp"
|
||||
attributes {
|
||||
"jsp.requestURL" "${baseUrl}/forwards/forwardToHtml.jsp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res.status().code() == 200
|
||||
}
|
||||
|
||||
def "non-erroneous GET forwarded to jsp with multiple includes"() {
|
||||
when:
|
||||
AggregatedHttpResponse res = client.get("/forwards/forwardToIncludeMulti.jsp").aggregate().join()
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 9) {
|
||||
span(0) {
|
||||
def route = "/$jspWebappContext/forwards/forwardToIncludeMulti.jsp"
|
||||
|
||||
hasNoParent()
|
||||
name "GET $route"
|
||||
kind SERVER
|
||||
attributes {
|
||||
"$UrlAttributes.URL_SCHEME" "http"
|
||||
"$UrlAttributes.URL_PATH" route
|
||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "GET"
|
||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200
|
||||
"$UserAgentAttributes.USER_AGENT_ORIGINAL" String
|
||||
"$HttpAttributes.HTTP_ROUTE" route
|
||||
"$NetworkAttributes.NETWORK_PROTOCOL_VERSION" "1.1"
|
||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
||||
"$ServerAttributes.SERVER_PORT" port
|
||||
"$ClientAttributes.CLIENT_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_PORT" Long
|
||||
}
|
||||
}
|
||||
span(1) {
|
||||
childOf span(0)
|
||||
name "Compile /forwards/forwardToIncludeMulti.jsp"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.forwards.forwardToIncludeMulti_jsp"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(2) {
|
||||
childOf span(0)
|
||||
name "Render /forwards/forwardToIncludeMulti.jsp"
|
||||
attributes {
|
||||
"jsp.requestURL" "${baseUrl}/forwards/forwardToIncludeMulti.jsp"
|
||||
}
|
||||
}
|
||||
span(3) {
|
||||
childOf span(2)
|
||||
name "Compile /includes/includeMulti.jsp"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.includes.includeMulti_jsp"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(4) {
|
||||
childOf span(2)
|
||||
name "Render /includes/includeMulti.jsp"
|
||||
attributes {
|
||||
"jsp.forwardOrigin" "/forwards/forwardToIncludeMulti.jsp"
|
||||
"jsp.requestURL" "${baseUrl}/includes/includeMulti.jsp"
|
||||
}
|
||||
}
|
||||
span(5) {
|
||||
childOf span(4)
|
||||
name "Compile /common/javaLoopH2.jsp"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.common.javaLoopH2_jsp"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(6) {
|
||||
childOf span(4)
|
||||
name "Render /common/javaLoopH2.jsp"
|
||||
attributes {
|
||||
"jsp.forwardOrigin" "/forwards/forwardToIncludeMulti.jsp"
|
||||
"jsp.requestURL" "${baseUrl}/includes/includeMulti.jsp"
|
||||
}
|
||||
}
|
||||
span(7) {
|
||||
childOf span(4)
|
||||
name "Compile /common/javaLoopH2.jsp"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.common.javaLoopH2_jsp"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(8) {
|
||||
childOf span(4)
|
||||
name "Render /common/javaLoopH2.jsp"
|
||||
attributes {
|
||||
"jsp.forwardOrigin" "/forwards/forwardToIncludeMulti.jsp"
|
||||
"jsp.requestURL" "${baseUrl}/includes/includeMulti.jsp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res.status().code() == 200
|
||||
}
|
||||
|
||||
def "non-erroneous GET forward to another forward (2 forwards)"() {
|
||||
when:
|
||||
AggregatedHttpResponse res = client.get("/forwards/forwardToJspForward.jsp").aggregate().join()
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 7) {
|
||||
span(0) {
|
||||
def route = "/$jspWebappContext/forwards/forwardToJspForward.jsp"
|
||||
|
||||
hasNoParent()
|
||||
name "GET $route"
|
||||
kind SERVER
|
||||
attributes {
|
||||
"$UrlAttributes.URL_SCHEME" "http"
|
||||
"$UrlAttributes.URL_PATH" route
|
||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "GET"
|
||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200
|
||||
"$UserAgentAttributes.USER_AGENT_ORIGINAL" String
|
||||
"$HttpAttributes.HTTP_ROUTE" route
|
||||
"$NetworkAttributes.NETWORK_PROTOCOL_VERSION" "1.1"
|
||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
||||
"$ServerAttributes.SERVER_PORT" port
|
||||
"$ClientAttributes.CLIENT_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_PORT" Long
|
||||
}
|
||||
}
|
||||
span(1) {
|
||||
childOf span(0)
|
||||
name "Compile /forwards/forwardToJspForward.jsp"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.forwards.forwardToJspForward_jsp"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(2) {
|
||||
childOf span(0)
|
||||
name "Render /forwards/forwardToJspForward.jsp"
|
||||
attributes {
|
||||
"jsp.requestURL" "${baseUrl}/forwards/forwardToJspForward.jsp"
|
||||
}
|
||||
}
|
||||
span(3) {
|
||||
childOf span(2)
|
||||
name "Compile /forwards/forwardToSimpleJava.jsp"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.forwards.forwardToSimpleJava_jsp"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(4) {
|
||||
childOf span(2)
|
||||
name "Render /forwards/forwardToSimpleJava.jsp"
|
||||
attributes {
|
||||
"jsp.forwardOrigin" "/forwards/forwardToJspForward.jsp"
|
||||
"jsp.requestURL" "${baseUrl}/forwards/forwardToSimpleJava.jsp"
|
||||
}
|
||||
}
|
||||
span(5) {
|
||||
childOf span(4)
|
||||
name "Compile /common/loop.jsp"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.common.loop_jsp"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(6) {
|
||||
childOf span(4)
|
||||
name "Render /common/loop.jsp"
|
||||
attributes {
|
||||
"jsp.forwardOrigin" "/forwards/forwardToJspForward.jsp"
|
||||
"jsp.requestURL" "${baseUrl}/common/loop.jsp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res.status().code() == 200
|
||||
}
|
||||
|
||||
def "forward to jsp with compile error should not produce a 2nd render span"() {
|
||||
when:
|
||||
AggregatedHttpResponse res = client.get("/forwards/forwardToCompileError.jsp").aggregate().join()
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 4) {
|
||||
span(0) {
|
||||
def route = "/$jspWebappContext/forwards/forwardToCompileError.jsp"
|
||||
|
||||
hasNoParent()
|
||||
name "GET $route"
|
||||
kind SERVER
|
||||
status ERROR
|
||||
errorEvent(JasperException, String)
|
||||
attributes {
|
||||
"$UrlAttributes.URL_SCHEME" "http"
|
||||
"$UrlAttributes.URL_PATH" route
|
||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "GET"
|
||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 500
|
||||
"$UserAgentAttributes.USER_AGENT_ORIGINAL" String
|
||||
"$HttpAttributes.HTTP_ROUTE" route
|
||||
"$NetworkAttributes.NETWORK_PROTOCOL_VERSION" "1.1"
|
||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
||||
"$ServerAttributes.SERVER_PORT" port
|
||||
"$ClientAttributes.CLIENT_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_PORT" Long
|
||||
"$ErrorAttributes.ERROR_TYPE" "500"
|
||||
}
|
||||
}
|
||||
span(1) {
|
||||
childOf span(0)
|
||||
name "Compile /forwards/forwardToCompileError.jsp"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.forwards.forwardToCompileError_jsp"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(2) {
|
||||
childOf span(0)
|
||||
name "Render /forwards/forwardToCompileError.jsp"
|
||||
status ERROR
|
||||
errorEvent(JasperException, String)
|
||||
attributes {
|
||||
"jsp.requestURL" "${baseUrl}/forwards/forwardToCompileError.jsp"
|
||||
}
|
||||
}
|
||||
span(3) {
|
||||
childOf span(2)
|
||||
name "Compile /compileError.jsp"
|
||||
status ERROR
|
||||
errorEvent(JasperException, String)
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.compileError_jsp"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res.status().code() == 500
|
||||
}
|
||||
|
||||
def "forward to non existent jsp should be 404"() {
|
||||
when:
|
||||
AggregatedHttpResponse res = client.get("/forwards/forwardToNonExistent.jsp").aggregate().join()
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 4) {
|
||||
span(0) {
|
||||
def route = "/$jspWebappContext/forwards/forwardToNonExistent.jsp"
|
||||
|
||||
hasNoParent()
|
||||
name "GET $route"
|
||||
kind SERVER
|
||||
status UNSET
|
||||
attributes {
|
||||
"$UrlAttributes.URL_SCHEME" "http"
|
||||
"$UrlAttributes.URL_PATH" route
|
||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "GET"
|
||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 404
|
||||
"$UserAgentAttributes.USER_AGENT_ORIGINAL" String
|
||||
"$HttpAttributes.HTTP_ROUTE" route
|
||||
"$NetworkAttributes.NETWORK_PROTOCOL_VERSION" "1.1"
|
||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
||||
"$ServerAttributes.SERVER_PORT" port
|
||||
"$ClientAttributes.CLIENT_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1"
|
||||
"$NetworkAttributes.NETWORK_PEER_PORT" Long
|
||||
}
|
||||
}
|
||||
span(1) {
|
||||
childOf span(0)
|
||||
name "Compile /forwards/forwardToNonExistent.jsp"
|
||||
attributes {
|
||||
"jsp.classFQCN" "org.apache.jsp.forwards.forwardToNonExistent_jsp"
|
||||
"jsp.compiler" "org.apache.jasper.compiler.JDTCompiler"
|
||||
}
|
||||
}
|
||||
span(2) {
|
||||
childOf span(0)
|
||||
name "Render /forwards/forwardToNonExistent.jsp"
|
||||
attributes {
|
||||
"jsp.requestURL" "${baseUrl}/forwards/forwardToNonExistent.jsp"
|
||||
}
|
||||
}
|
||||
span(3) {
|
||||
childOf span(2)
|
||||
name "ResponseFacade.sendError"
|
||||
}
|
||||
}
|
||||
}
|
||||
res.status().code() == 404
|
||||
}
|
||||
}
|
|
@ -0,0 +1,488 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.jsp;
|
||||
|
||||
import static io.opentelemetry.api.common.AttributeKey.stringKey;
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies;
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
|
||||
import io.opentelemetry.api.trace.SpanKind;
|
||||
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerUsingTest;
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension;
|
||||
import io.opentelemetry.sdk.trace.data.StatusData;
|
||||
import io.opentelemetry.semconv.ClientAttributes;
|
||||
import io.opentelemetry.semconv.ExceptionAttributes;
|
||||
import io.opentelemetry.semconv.HttpAttributes;
|
||||
import io.opentelemetry.semconv.NetworkAttributes;
|
||||
import io.opentelemetry.semconv.ServerAttributes;
|
||||
import io.opentelemetry.semconv.UrlAttributes;
|
||||
import io.opentelemetry.semconv.UserAgentAttributes;
|
||||
import io.opentelemetry.testing.internal.armeria.client.WebClient;
|
||||
import io.opentelemetry.testing.internal.armeria.common.AggregatedHttpResponse;
|
||||
import io.opentelemetry.testing.internal.armeria.common.HttpMethod;
|
||||
import io.opentelemetry.testing.internal.armeria.common.MediaType;
|
||||
import io.opentelemetry.testing.internal.armeria.common.RequestHeaders;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.util.stream.Stream;
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
import org.apache.jasper.JasperException;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
class JspInstrumentationBasicTests extends AbstractHttpServerUsingTest<Tomcat> {
|
||||
|
||||
@RegisterExtension
|
||||
public static final InstrumentationExtension testing =
|
||||
HttpServerInstrumentationExtension.forAgent();
|
||||
|
||||
private static JspSpanAssertions spanAsserts;
|
||||
|
||||
@Override
|
||||
protected Tomcat setupServer() throws Exception {
|
||||
File baseDir = Files.createTempDirectory("jsp").toFile();
|
||||
baseDir.deleteOnExit();
|
||||
|
||||
Tomcat tomcatServer = new Tomcat();
|
||||
tomcatServer.setBaseDir(baseDir.getAbsolutePath());
|
||||
tomcatServer.setPort(port);
|
||||
tomcatServer.getConnector();
|
||||
|
||||
// comment to debug
|
||||
tomcatServer.setSilent(true);
|
||||
|
||||
// this is needed in tomcat 9, this triggers the creation of a connector, will not
|
||||
// affect tomcat 7 and 8
|
||||
// https://stackoverflow.com/questions/48998387/code-works-with-embedded-apache-tomcat-8-but-not-with-9-whats-changed
|
||||
tomcatServer.getConnector();
|
||||
|
||||
String baseUrl = "http://localhost:" + port + "/" + getContextPath();
|
||||
spanAsserts = new JspSpanAssertions(baseUrl, port);
|
||||
client = WebClient.of(baseUrl);
|
||||
|
||||
tomcatServer.addWebapp(
|
||||
"/" + getContextPath(),
|
||||
JspInstrumentationBasicTests.class.getResource("/webapps/jsptest").getPath());
|
||||
|
||||
tomcatServer.start();
|
||||
return tomcatServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stopServer(Tomcat tomcat) throws Exception {
|
||||
tomcat.stop();
|
||||
tomcat.destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getContextPath() {
|
||||
return "jsptest-context";
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
protected void setUp() {
|
||||
startServer();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
protected void cleanUp() {
|
||||
cleanupServer();
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "GET {0}")
|
||||
@ArgumentsSource(NonErroneousArgs.class)
|
||||
void testNonErroneousGet(
|
||||
String testName, String jspFileName, String jspClassName, String jspClassNamePrefix) {
|
||||
AggregatedHttpResponse res = client.get(jspFileName).aggregate().join();
|
||||
assertThat(res.status().code()).isEqualTo(200);
|
||||
|
||||
testing.waitAndAssertTraces(
|
||||
trace ->
|
||||
trace.hasSpansSatisfyingExactly(
|
||||
span ->
|
||||
spanAsserts.assertServerSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withMethod("GET")
|
||||
.withRoute("/" + getContextPath() + jspFileName)
|
||||
.withResponseStatus(200)
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute(jspFileName)
|
||||
.withClassName(jspClassNamePrefix + jspClassName)
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute(jspFileName)
|
||||
.build())));
|
||||
}
|
||||
|
||||
static class NonErroneousArgs implements ArgumentsProvider {
|
||||
@Override
|
||||
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
|
||||
return Stream.of(
|
||||
Arguments.of("no java jsp", "/nojava.jsp", "nojava_jsp", ""),
|
||||
Arguments.of("basic loop jsp", "/common/loop.jsp", "loop_jsp", "common."),
|
||||
Arguments.of("invalid HTML markup", "/invalidMarkup.jsp", "invalidMarkup_jsp", ""));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNonErroneousGetWithQueryString() {
|
||||
String queryString = "HELLO";
|
||||
String route = "/" + getContextPath() + "/getQuery.jsp";
|
||||
|
||||
AggregatedHttpResponse res = client.get("/getQuery.jsp?" + queryString).aggregate().join();
|
||||
assertThat(res.status().code()).isEqualTo(200);
|
||||
|
||||
testing.waitAndAssertTraces(
|
||||
trace ->
|
||||
trace.hasSpansSatisfyingExactly(
|
||||
span ->
|
||||
span.hasName("GET " + route)
|
||||
.hasNoParent()
|
||||
.hasKind(SpanKind.SERVER)
|
||||
.hasAttributesSatisfyingExactly(
|
||||
equalTo(UrlAttributes.URL_SCHEME, "http"),
|
||||
equalTo(UrlAttributes.URL_PATH, route),
|
||||
equalTo(UrlAttributes.URL_QUERY, queryString),
|
||||
equalTo(HttpAttributes.HTTP_REQUEST_METHOD, "GET"),
|
||||
equalTo(HttpAttributes.HTTP_RESPONSE_STATUS_CODE, 200),
|
||||
satisfies(
|
||||
UserAgentAttributes.USER_AGENT_ORIGINAL,
|
||||
val -> val.isInstanceOf(String.class)),
|
||||
equalTo(HttpAttributes.HTTP_ROUTE, route),
|
||||
equalTo(NetworkAttributes.NETWORK_PROTOCOL_VERSION, "1.1"),
|
||||
equalTo(ServerAttributes.SERVER_ADDRESS, "localhost"),
|
||||
equalTo(ServerAttributes.SERVER_PORT, port),
|
||||
equalTo(ClientAttributes.CLIENT_ADDRESS, "127.0.0.1"),
|
||||
equalTo(NetworkAttributes.NETWORK_PEER_ADDRESS, "127.0.0.1"),
|
||||
satisfies(
|
||||
NetworkAttributes.NETWORK_PEER_PORT,
|
||||
val -> val.isInstanceOf(Long.class))),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute("/getQuery.jsp")
|
||||
.withClassName("getQuery_jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute("/getQuery.jsp")
|
||||
.build())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNonErroneousPost() {
|
||||
RequestHeaders headers =
|
||||
RequestHeaders.builder(HttpMethod.POST, "/post.jsp")
|
||||
.contentType(MediaType.FORM_DATA)
|
||||
.build();
|
||||
|
||||
AggregatedHttpResponse res = client.execute(headers, "name=world").aggregate().join();
|
||||
assertThat(res.status().code()).isEqualTo(200);
|
||||
|
||||
testing.waitAndAssertTraces(
|
||||
trace ->
|
||||
trace.hasSpansSatisfyingExactly(
|
||||
span ->
|
||||
spanAsserts.assertServerSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withMethod("POST")
|
||||
.withRoute("/" + getContextPath() + "/post.jsp")
|
||||
.withResponseStatus(200)
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute("/post.jsp")
|
||||
.withClassName("post_jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute("/post.jsp")
|
||||
.build())));
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "GET jsp with {0}")
|
||||
@ArgumentsSource(ErroneousRuntimeErrorsArgs.class)
|
||||
void testErroneousRuntimeErrorsGet(
|
||||
String testName,
|
||||
String jspFileName,
|
||||
String jspClassName,
|
||||
Class<?> exceptionClass,
|
||||
boolean errorMessageOptional) {
|
||||
AggregatedHttpResponse res = client.get(jspFileName).aggregate().join();
|
||||
assertThat(res.status().code()).isEqualTo(500);
|
||||
|
||||
testing.waitAndAssertTraces(
|
||||
trace ->
|
||||
trace.hasSpansSatisfyingExactly(
|
||||
span ->
|
||||
spanAsserts.assertServerSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withMethod("GET")
|
||||
.withRoute("/" + getContextPath() + jspFileName)
|
||||
.withResponseStatus(500)
|
||||
.withExceptionClass(exceptionClass)
|
||||
.withErrorMessageOptional(errorMessageOptional)
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute(jspFileName)
|
||||
.withClassName(jspClassName)
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute(jspFileName)
|
||||
.withErrorMessageOptional(errorMessageOptional)
|
||||
.build())));
|
||||
}
|
||||
|
||||
static class ErroneousRuntimeErrorsArgs implements ArgumentsProvider {
|
||||
@Override
|
||||
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
|
||||
return Stream.of(
|
||||
Arguments.of(
|
||||
"java runtime error",
|
||||
"/runtimeError.jsp",
|
||||
"runtimeError_jsp",
|
||||
ArithmeticException.class,
|
||||
false),
|
||||
Arguments.of(
|
||||
"invalid write",
|
||||
"/invalidWrite.jsp",
|
||||
"invalidWrite_jsp",
|
||||
IndexOutOfBoundsException.class,
|
||||
true),
|
||||
Arguments.of(
|
||||
"invalid write", "/getQuery.jsp", "getQuery_jsp", NullPointerException.class, true));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNonErroneousIncludePlainHtmlGet() {
|
||||
AggregatedHttpResponse res = client.get("/includes/includeHtml.jsp").aggregate().join();
|
||||
assertThat(res.status().code()).isEqualTo(200);
|
||||
|
||||
testing.waitAndAssertTraces(
|
||||
trace ->
|
||||
trace.hasSpansSatisfyingExactly(
|
||||
span ->
|
||||
spanAsserts.assertServerSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withMethod("GET")
|
||||
.withRoute("/" + getContextPath() + "/includes/includeHtml.jsp")
|
||||
.withResponseStatus(200)
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute("/includes/includeHtml.jsp")
|
||||
.withClassName("includes.includeHtml_jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute("/includes/includeHtml.jsp")
|
||||
.build())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNonErroneousMultiGet() {
|
||||
AggregatedHttpResponse res = client.get("/includes/includeMulti.jsp").aggregate().join();
|
||||
assertThat(res.status().code()).isEqualTo(200);
|
||||
|
||||
testing.waitAndAssertTraces(
|
||||
trace ->
|
||||
trace.hasSpansSatisfyingExactly(
|
||||
span ->
|
||||
spanAsserts.assertServerSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withMethod("GET")
|
||||
.withRoute("/" + getContextPath() + "/includes/includeMulti.jsp")
|
||||
.withResponseStatus(200)
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute("/includes/includeMulti.jsp")
|
||||
.withClassName("includes.includeMulti_jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute("/includes/includeMulti.jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(2))
|
||||
.withRoute("/common/javaLoopH2.jsp")
|
||||
.withClassName("common.javaLoopH2_jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(2))
|
||||
.withRoute("/common/javaLoopH2.jsp")
|
||||
.withRequestUrlOverride("/includes/includeMulti.jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(2))
|
||||
.withRoute("/common/javaLoopH2.jsp")
|
||||
.withClassName("common.javaLoopH2_jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(2))
|
||||
.withRoute("/common/javaLoopH2.jsp")
|
||||
.withRequestUrlOverride("/includes/includeMulti.jsp")
|
||||
.build())));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(CompileErrorsArgs.class)
|
||||
void testCompileErrorShouldNotProduceRenderTracesAndSpans(
|
||||
String jspFileName, String jspClassName, String jspClassNamePrefix) {
|
||||
AggregatedHttpResponse res = client.get(jspFileName).aggregate().join();
|
||||
assertThat(res.status().code()).isEqualTo(500);
|
||||
|
||||
testing.waitAndAssertTraces(
|
||||
trace ->
|
||||
trace.hasSpansSatisfyingExactly(
|
||||
span ->
|
||||
spanAsserts.assertServerSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withMethod("GET")
|
||||
.withRoute("/" + getContextPath() + jspFileName)
|
||||
.withResponseStatus(500)
|
||||
.withExceptionClass(JasperException.class)
|
||||
.build()),
|
||||
span ->
|
||||
span.hasName("Compile " + jspFileName)
|
||||
.hasParent(trace.getSpan(0))
|
||||
.hasStatus(StatusData.error())
|
||||
.hasEventsSatisfyingExactly(
|
||||
event ->
|
||||
event
|
||||
.hasName("exception")
|
||||
.hasAttributesSatisfyingExactly(
|
||||
equalTo(
|
||||
ExceptionAttributes.EXCEPTION_TYPE,
|
||||
JasperException.class.getCanonicalName()),
|
||||
satisfies(
|
||||
ExceptionAttributes.EXCEPTION_STACKTRACE,
|
||||
val -> val.isInstanceOf(String.class)),
|
||||
satisfies(
|
||||
ExceptionAttributes.EXCEPTION_MESSAGE,
|
||||
val -> val.isInstanceOf(String.class))))
|
||||
.hasAttributesSatisfyingExactly(
|
||||
equalTo(
|
||||
stringKey("jsp.classFQCN"),
|
||||
"org.apache.jsp." + jspClassNamePrefix + jspClassName),
|
||||
equalTo(
|
||||
stringKey("jsp.compiler"),
|
||||
"org.apache.jasper.compiler.JDTCompiler"))));
|
||||
}
|
||||
|
||||
static class CompileErrorsArgs implements ArgumentsProvider {
|
||||
@Override
|
||||
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
|
||||
return Stream.of(
|
||||
Arguments.of("/compileError.jsp", "compileError_jsp", ""),
|
||||
Arguments.of(
|
||||
"/forwards/forwardWithCompileError.jsp", "forwardWithCompileError_jsp", "forwards."));
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"/common/hello.html"})
|
||||
void testDirectStaticFileReference(String staticFile) {
|
||||
String route = "/" + getContextPath() + "/*";
|
||||
|
||||
AggregatedHttpResponse res = client.get(staticFile).aggregate().join();
|
||||
assertThat(res.status().code()).isEqualTo(200);
|
||||
|
||||
testing.waitAndAssertTraces(
|
||||
trace ->
|
||||
trace.hasSpansSatisfyingExactly(
|
||||
span ->
|
||||
span.hasName("GET " + route)
|
||||
.hasNoParent()
|
||||
.hasKind(SpanKind.SERVER)
|
||||
.hasAttributesSatisfyingExactly(
|
||||
equalTo(UrlAttributes.URL_SCHEME, "http"),
|
||||
equalTo(UrlAttributes.URL_PATH, "/" + getContextPath() + staticFile),
|
||||
equalTo(HttpAttributes.HTTP_REQUEST_METHOD, "GET"),
|
||||
equalTo(HttpAttributes.HTTP_RESPONSE_STATUS_CODE, 200),
|
||||
satisfies(
|
||||
UserAgentAttributes.USER_AGENT_ORIGINAL,
|
||||
val -> val.isInstanceOf(String.class)),
|
||||
equalTo(HttpAttributes.HTTP_ROUTE, route),
|
||||
equalTo(NetworkAttributes.NETWORK_PROTOCOL_VERSION, "1.1"),
|
||||
equalTo(ServerAttributes.SERVER_ADDRESS, "localhost"),
|
||||
equalTo(ServerAttributes.SERVER_PORT, port),
|
||||
equalTo(ClientAttributes.CLIENT_ADDRESS, "127.0.0.1"),
|
||||
equalTo(NetworkAttributes.NETWORK_PEER_ADDRESS, "127.0.0.1"),
|
||||
satisfies(
|
||||
NetworkAttributes.NETWORK_PEER_PORT,
|
||||
val -> val.isInstanceOf(Long.class)))));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,454 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.jsp;
|
||||
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies;
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
|
||||
import io.opentelemetry.api.trace.SpanKind;
|
||||
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerUsingTest;
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension;
|
||||
import io.opentelemetry.sdk.trace.data.StatusData;
|
||||
import io.opentelemetry.semconv.ClientAttributes;
|
||||
import io.opentelemetry.semconv.HttpAttributes;
|
||||
import io.opentelemetry.semconv.NetworkAttributes;
|
||||
import io.opentelemetry.semconv.ServerAttributes;
|
||||
import io.opentelemetry.semconv.UrlAttributes;
|
||||
import io.opentelemetry.semconv.UserAgentAttributes;
|
||||
import io.opentelemetry.testing.internal.armeria.client.WebClient;
|
||||
import io.opentelemetry.testing.internal.armeria.common.AggregatedHttpResponse;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.util.stream.Stream;
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
import org.apache.jasper.JasperException;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
|
||||
class JspInstrumentationForwardTests extends AbstractHttpServerUsingTest<Tomcat> {
|
||||
|
||||
@RegisterExtension
|
||||
public static final InstrumentationExtension testing =
|
||||
HttpServerInstrumentationExtension.forAgent();
|
||||
|
||||
private static JspSpanAssertions spanAsserts;
|
||||
|
||||
@Override
|
||||
protected Tomcat setupServer() throws Exception {
|
||||
File baseDir = Files.createTempDirectory("jsp").toFile();
|
||||
baseDir.deleteOnExit();
|
||||
|
||||
Tomcat tomcatServer = new Tomcat();
|
||||
tomcatServer.setBaseDir(baseDir.getAbsolutePath());
|
||||
tomcatServer.setPort(port);
|
||||
tomcatServer.getConnector();
|
||||
|
||||
// comment to debug
|
||||
tomcatServer.setSilent(true);
|
||||
|
||||
// this is needed in tomcat 9, this triggers the creation of a connector, will not
|
||||
// affect tomcat 7 and 8
|
||||
// https://stackoverflow.com/questions/48998387/code-works-with-embedded-apache-tomcat-8-but-not-with-9-whats-changed
|
||||
tomcatServer.getConnector();
|
||||
|
||||
String baseUrl = "http://localhost:" + port + "/" + getContextPath();
|
||||
spanAsserts = new JspSpanAssertions(baseUrl, port);
|
||||
client = WebClient.of(baseUrl);
|
||||
|
||||
tomcatServer.addWebapp(
|
||||
"/" + getContextPath(),
|
||||
JspInstrumentationForwardTests.class.getResource("/webapps/jsptest").getPath());
|
||||
|
||||
tomcatServer.start();
|
||||
return tomcatServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stopServer(Tomcat tomcat) throws Exception {
|
||||
tomcat.stop();
|
||||
tomcat.destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getContextPath() {
|
||||
return "jsptest-context";
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
protected void setUp() {
|
||||
startServer();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
protected void cleanUp() {
|
||||
cleanupServer();
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "Forward to {0}")
|
||||
@ArgumentsSource(NonErroneousGetForwardArgs.class)
|
||||
void testNonErroneousGetForwardTo(
|
||||
String name,
|
||||
String forwardFromFileName,
|
||||
String forwardDestFileName,
|
||||
String jspForwardFromClassName,
|
||||
String jspForwardFromClassPrefix,
|
||||
String jspForwardDestClassName,
|
||||
String jspForwardDestClassPrefix) {
|
||||
AggregatedHttpResponse res = client.get(forwardFromFileName).aggregate().join();
|
||||
assertThat(res.status().code()).isEqualTo(200);
|
||||
|
||||
testing.waitAndAssertTraces(
|
||||
trace ->
|
||||
trace.hasSpansSatisfyingExactly(
|
||||
span ->
|
||||
spanAsserts.assertServerSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withMethod("GET")
|
||||
.withRoute("/" + getContextPath() + forwardFromFileName)
|
||||
.withResponseStatus(200)
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute(forwardFromFileName)
|
||||
.withClassName(jspForwardFromClassPrefix + jspForwardFromClassName)
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute(forwardFromFileName)
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(2))
|
||||
.withRoute(forwardDestFileName)
|
||||
.withClassName(jspForwardDestClassPrefix + jspForwardDestClassName)
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(2))
|
||||
.withRoute(forwardDestFileName)
|
||||
.build())));
|
||||
}
|
||||
|
||||
static class NonErroneousGetForwardArgs implements ArgumentsProvider {
|
||||
@Override
|
||||
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
|
||||
return Stream.of(
|
||||
Arguments.of(
|
||||
"no java jsp",
|
||||
"/forwards/forwardToNoJavaJsp.jsp",
|
||||
"/nojava.jsp",
|
||||
"forwardToNoJavaJsp_jsp",
|
||||
"forwards.",
|
||||
"nojava_jsp",
|
||||
""),
|
||||
Arguments.of(
|
||||
"normal java jsp",
|
||||
"/forwards/forwardToSimpleJava.jsp",
|
||||
"/common/loop.jsp",
|
||||
"forwardToSimpleJava_jsp",
|
||||
"forwards.",
|
||||
"loop_jsp",
|
||||
"common."));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNonErroneousGetForwardToPlainHtml() {
|
||||
AggregatedHttpResponse res = client.get("/forwards/forwardToHtml.jsp").aggregate().join();
|
||||
assertThat(res.status().code()).isEqualTo(200);
|
||||
|
||||
testing.waitAndAssertTraces(
|
||||
trace ->
|
||||
trace.hasSpansSatisfyingExactly(
|
||||
span ->
|
||||
spanAsserts.assertServerSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withMethod("GET")
|
||||
.withRoute("/" + getContextPath() + "/forwards/forwardToHtml.jsp")
|
||||
.withResponseStatus(200)
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute("/forwards/forwardToHtml.jsp")
|
||||
.withClassName("forwards.forwardToHtml_jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute("/forwards/forwardToHtml.jsp")
|
||||
.build())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNonErroneousGetForwardedToJspWithMultipleIncludes() {
|
||||
AggregatedHttpResponse res =
|
||||
client.get("/forwards/forwardToIncludeMulti.jsp").aggregate().join();
|
||||
assertThat(res.status().code()).isEqualTo(200);
|
||||
|
||||
testing.waitAndAssertTraces(
|
||||
trace ->
|
||||
trace.hasSpansSatisfyingExactly(
|
||||
span ->
|
||||
spanAsserts.assertServerSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withMethod("GET")
|
||||
.withRoute(
|
||||
"/" + getContextPath() + "/forwards/forwardToIncludeMulti.jsp")
|
||||
.withResponseStatus(200)
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute("/forwards/forwardToIncludeMulti.jsp")
|
||||
.withClassName("forwards.forwardToIncludeMulti_jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute("/forwards/forwardToIncludeMulti.jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(2))
|
||||
.withRoute("/includes/includeMulti.jsp")
|
||||
.withClassName("includes.includeMulti_jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(2))
|
||||
.withRoute("/includes/includeMulti.jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(4))
|
||||
.withRoute("/common/javaLoopH2.jsp")
|
||||
.withClassName("common.javaLoopH2_jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(4))
|
||||
.withRoute("/common/javaLoopH2.jsp")
|
||||
.withRequestUrlOverride("/includes/includeMulti.jsp")
|
||||
.withForwardOrigin("/forwards/forwardToIncludeMulti.jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(4))
|
||||
.withRoute("/common/javaLoopH2.jsp")
|
||||
.withClassName("common.javaLoopH2_jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(4))
|
||||
.withRoute("/common/javaLoopH2.jsp")
|
||||
.withRequestUrlOverride("/includes/includeMulti.jsp")
|
||||
.withForwardOrigin("/forwards/forwardToIncludeMulti.jsp")
|
||||
.build())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNonErroneousGetForwardToAnotherForward() {
|
||||
AggregatedHttpResponse res = client.get("/forwards/forwardToJspForward.jsp").aggregate().join();
|
||||
assertThat(res.status().code()).isEqualTo(200);
|
||||
|
||||
testing.waitAndAssertTraces(
|
||||
trace ->
|
||||
trace.hasSpansSatisfyingExactly(
|
||||
span ->
|
||||
spanAsserts.assertServerSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withMethod("GET")
|
||||
.withRoute("/" + getContextPath() + "/forwards/forwardToJspForward.jsp")
|
||||
.withResponseStatus(200)
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute("/forwards/forwardToJspForward.jsp")
|
||||
.withClassName("forwards.forwardToJspForward_jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute("/forwards/forwardToJspForward.jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(2))
|
||||
.withRoute("/forwards/forwardToSimpleJava.jsp")
|
||||
.withClassName("forwards.forwardToSimpleJava_jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(2))
|
||||
.withRoute("/forwards/forwardToSimpleJava.jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(4))
|
||||
.withRoute("/common/loop.jsp")
|
||||
.withClassName("common.loop_jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(4))
|
||||
.withRoute("/common/loop.jsp")
|
||||
.build())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testForwardToJspWithCompileErrorShouldNotProduceSecondRenderSpan() {
|
||||
AggregatedHttpResponse res =
|
||||
client.get("/forwards/forwardToCompileError.jsp").aggregate().join();
|
||||
assertThat(res.status().code()).isEqualTo(500);
|
||||
|
||||
testing.waitAndAssertTraces(
|
||||
trace ->
|
||||
trace.hasSpansSatisfyingExactly(
|
||||
span ->
|
||||
spanAsserts.assertServerSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withMethod("GET")
|
||||
.withRoute(
|
||||
"/" + getContextPath() + "/forwards/forwardToCompileError.jsp")
|
||||
.withResponseStatus(500)
|
||||
.withExceptionClass(JasperException.class)
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute("/forwards/forwardToCompileError.jsp")
|
||||
.withClassName("forwards.forwardToCompileError_jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute("/forwards/forwardToCompileError.jsp")
|
||||
.withExceptionClass(JasperException.class)
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(2))
|
||||
.withRoute("/compileError.jsp")
|
||||
.withClassName("compileError_jsp")
|
||||
.withExceptionClass(JasperException.class)
|
||||
.build())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testForwardToNonExistentJspShouldBe404() {
|
||||
String route = "/" + getContextPath() + "/forwards/forwardToNonExistent.jsp";
|
||||
|
||||
AggregatedHttpResponse res =
|
||||
client.get("/forwards/forwardToNonExistent.jsp").aggregate().join();
|
||||
assertThat(res.status().code()).isEqualTo(404);
|
||||
|
||||
testing.waitAndAssertTraces(
|
||||
trace ->
|
||||
trace.hasSpansSatisfyingExactly(
|
||||
span ->
|
||||
span.hasName("GET " + route)
|
||||
.hasNoParent()
|
||||
.hasKind(SpanKind.SERVER)
|
||||
.hasStatus(StatusData.unset())
|
||||
.hasAttributesSatisfyingExactly(
|
||||
equalTo(UrlAttributes.URL_SCHEME, "http"),
|
||||
equalTo(UrlAttributes.URL_PATH, route),
|
||||
equalTo(HttpAttributes.HTTP_REQUEST_METHOD, "GET"),
|
||||
equalTo(HttpAttributes.HTTP_RESPONSE_STATUS_CODE, 404),
|
||||
satisfies(
|
||||
UserAgentAttributes.USER_AGENT_ORIGINAL,
|
||||
val -> val.isInstanceOf(String.class)),
|
||||
equalTo(HttpAttributes.HTTP_ROUTE, route),
|
||||
equalTo(NetworkAttributes.NETWORK_PROTOCOL_VERSION, "1.1"),
|
||||
equalTo(ServerAttributes.SERVER_ADDRESS, "localhost"),
|
||||
equalTo(ServerAttributes.SERVER_PORT, port),
|
||||
equalTo(ClientAttributes.CLIENT_ADDRESS, "127.0.0.1"),
|
||||
equalTo(NetworkAttributes.NETWORK_PEER_ADDRESS, "127.0.0.1"),
|
||||
satisfies(
|
||||
NetworkAttributes.NETWORK_PEER_PORT,
|
||||
val -> val.isInstanceOf(Long.class))),
|
||||
span ->
|
||||
spanAsserts.assertCompileSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute("/forwards/forwardToNonExistent.jsp")
|
||||
.withClassName("forwards.forwardToNonExistent_jsp")
|
||||
.build()),
|
||||
span ->
|
||||
spanAsserts.assertRenderSpan(
|
||||
span,
|
||||
new JspSpanAssertionBuilder()
|
||||
.withParent(trace.getSpan(0))
|
||||
.withRoute("/forwards/forwardToNonExistent.jsp")
|
||||
.build()),
|
||||
span -> span.hasName("ResponseFacade.sendError").hasParent(trace.getSpan(2))));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.jsp;
|
||||
|
||||
import io.opentelemetry.sdk.trace.data.SpanData;
|
||||
|
||||
class JspSpan {
|
||||
private SpanData parent;
|
||||
private String method;
|
||||
private String className;
|
||||
private String requestUrlOverride;
|
||||
private String forwardOrigin;
|
||||
private String route;
|
||||
private int responseStatus;
|
||||
private Class<?> exceptionClass;
|
||||
private boolean errorMessageOptional;
|
||||
|
||||
public SpanData getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(SpanData parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public void setMethod(String method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
public void setClassName(String className) {
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
public String getRequestUrlOverride() {
|
||||
return requestUrlOverride;
|
||||
}
|
||||
|
||||
public void setRequestUrlOverride(String requestUrlOverride) {
|
||||
this.requestUrlOverride = requestUrlOverride;
|
||||
}
|
||||
|
||||
public String getForwardOrigin() {
|
||||
return forwardOrigin;
|
||||
}
|
||||
|
||||
public void setForwardOrigin(String forwardOrigin) {
|
||||
this.forwardOrigin = forwardOrigin;
|
||||
}
|
||||
|
||||
public String getRoute() {
|
||||
return route;
|
||||
}
|
||||
|
||||
public void setRoute(String route) {
|
||||
this.route = route;
|
||||
}
|
||||
|
||||
public int getResponseStatus() {
|
||||
return responseStatus;
|
||||
}
|
||||
|
||||
public void setResponseStatus(int responseStatus) {
|
||||
this.responseStatus = responseStatus;
|
||||
}
|
||||
|
||||
public Class<?> getExceptionClass() {
|
||||
return exceptionClass;
|
||||
}
|
||||
|
||||
public void setExceptionClass(Class<?> exceptionClass) {
|
||||
this.exceptionClass = exceptionClass;
|
||||
}
|
||||
|
||||
public boolean getErrorMessageOptional() {
|
||||
return errorMessageOptional;
|
||||
}
|
||||
|
||||
public void setErrorMessageOptional(boolean errorMessageOptional) {
|
||||
this.errorMessageOptional = errorMessageOptional;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.jsp;
|
||||
|
||||
import io.opentelemetry.sdk.trace.data.SpanData;
|
||||
|
||||
class JspSpanAssertionBuilder {
|
||||
private SpanData parent;
|
||||
private String method;
|
||||
private String route;
|
||||
private String className;
|
||||
private String requestUrlOverride;
|
||||
private String forwardOrigin;
|
||||
private int responseStatus;
|
||||
private Class<?> exceptionClass;
|
||||
private boolean errorMessageOptional;
|
||||
|
||||
public JspSpanAssertionBuilder withParent(SpanData parent) {
|
||||
this.parent = parent;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JspSpanAssertionBuilder withMethod(String method) {
|
||||
this.method = method;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JspSpanAssertionBuilder withRoute(String route) {
|
||||
this.route = route;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JspSpanAssertionBuilder withClassName(String className) {
|
||||
this.className = className;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JspSpanAssertionBuilder withRequestUrlOverride(String requestUrlOverride) {
|
||||
this.requestUrlOverride = requestUrlOverride;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JspSpanAssertionBuilder withForwardOrigin(String forwardOrigin) {
|
||||
this.forwardOrigin = forwardOrigin;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JspSpanAssertionBuilder withResponseStatus(int responseStatus) {
|
||||
this.responseStatus = responseStatus;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JspSpanAssertionBuilder withExceptionClass(Class<?> exceptionClass) {
|
||||
this.exceptionClass = exceptionClass;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JspSpanAssertionBuilder withErrorMessageOptional(boolean errorMessageOptional) {
|
||||
this.errorMessageOptional = errorMessageOptional;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JspSpan build() {
|
||||
JspSpan serverSpan = new JspSpan();
|
||||
serverSpan.setParent(this.parent);
|
||||
serverSpan.setMethod(this.method);
|
||||
serverSpan.setRoute(this.route);
|
||||
serverSpan.setClassName(this.className);
|
||||
serverSpan.setRequestUrlOverride(this.requestUrlOverride);
|
||||
serverSpan.setForwardOrigin(this.forwardOrigin);
|
||||
serverSpan.setResponseStatus(this.responseStatus);
|
||||
serverSpan.setExceptionClass(this.exceptionClass);
|
||||
serverSpan.setErrorMessageOptional(this.errorMessageOptional);
|
||||
return serverSpan;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.jsp;
|
||||
|
||||
import static io.opentelemetry.api.common.AttributeKey.stringKey;
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.opentelemetry.api.trace.SpanKind;
|
||||
import io.opentelemetry.sdk.testing.assertj.SpanDataAssert;
|
||||
import io.opentelemetry.sdk.trace.data.StatusData;
|
||||
import io.opentelemetry.semconv.ClientAttributes;
|
||||
import io.opentelemetry.semconv.ErrorAttributes;
|
||||
import io.opentelemetry.semconv.ExceptionAttributes;
|
||||
import io.opentelemetry.semconv.HttpAttributes;
|
||||
import io.opentelemetry.semconv.NetworkAttributes;
|
||||
import io.opentelemetry.semconv.ServerAttributes;
|
||||
import io.opentelemetry.semconv.UrlAttributes;
|
||||
import io.opentelemetry.semconv.UserAgentAttributes;
|
||||
|
||||
class JspSpanAssertions {
|
||||
private final String baseUrl;
|
||||
private final int port;
|
||||
|
||||
JspSpanAssertions(String baseUrl, int port) {
|
||||
this.baseUrl = baseUrl;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
SpanDataAssert assertServerSpan(SpanDataAssert span, JspSpan spanData) {
|
||||
if (spanData.getExceptionClass() != null) {
|
||||
span.hasStatus(StatusData.error())
|
||||
.hasEventsSatisfyingExactly(
|
||||
event ->
|
||||
event
|
||||
.hasName("exception")
|
||||
.hasAttributesSatisfyingExactly(
|
||||
satisfies(
|
||||
ExceptionAttributes.EXCEPTION_TYPE,
|
||||
val ->
|
||||
val.satisfiesAnyOf(
|
||||
v -> val.isEqualTo(spanData.getExceptionClass().getName()),
|
||||
v ->
|
||||
val.contains(
|
||||
spanData.getExceptionClass().getSimpleName()))),
|
||||
satisfies(
|
||||
ExceptionAttributes.EXCEPTION_MESSAGE,
|
||||
val ->
|
||||
val.satisfiesAnyOf(
|
||||
v -> assertThat(spanData.getErrorMessageOptional()).isTrue(),
|
||||
v -> val.isInstanceOf(String.class))),
|
||||
satisfies(
|
||||
ExceptionAttributes.EXCEPTION_STACKTRACE,
|
||||
val -> val.isInstanceOf(String.class))));
|
||||
}
|
||||
|
||||
return span.hasName(spanData.getMethod() + " " + spanData.getRoute())
|
||||
.hasNoParent()
|
||||
.hasKind(SpanKind.SERVER)
|
||||
.hasAttributesSatisfyingExactly(
|
||||
equalTo(UrlAttributes.URL_SCHEME, "http"),
|
||||
equalTo(UrlAttributes.URL_PATH, spanData.getRoute()),
|
||||
equalTo(HttpAttributes.HTTP_REQUEST_METHOD, spanData.getMethod()),
|
||||
equalTo(HttpAttributes.HTTP_RESPONSE_STATUS_CODE, spanData.getResponseStatus()),
|
||||
satisfies(
|
||||
UserAgentAttributes.USER_AGENT_ORIGINAL, val -> val.isInstanceOf(String.class)),
|
||||
equalTo(HttpAttributes.HTTP_ROUTE, spanData.getRoute()),
|
||||
equalTo(NetworkAttributes.NETWORK_PROTOCOL_VERSION, "1.1"),
|
||||
equalTo(ServerAttributes.SERVER_ADDRESS, "localhost"),
|
||||
equalTo(ServerAttributes.SERVER_PORT, port),
|
||||
equalTo(ClientAttributes.CLIENT_ADDRESS, "127.0.0.1"),
|
||||
equalTo(NetworkAttributes.NETWORK_PEER_ADDRESS, "127.0.0.1"),
|
||||
satisfies(NetworkAttributes.NETWORK_PEER_PORT, val -> val.isInstanceOf(Long.class)),
|
||||
satisfies(
|
||||
ErrorAttributes.ERROR_TYPE,
|
||||
val ->
|
||||
val.satisfiesAnyOf(
|
||||
v -> assertThat(spanData.getExceptionClass()).isNull(),
|
||||
v -> assertThat(v).isEqualTo("500"))));
|
||||
}
|
||||
|
||||
SpanDataAssert assertCompileSpan(SpanDataAssert span, JspSpan spanData) {
|
||||
if (spanData.getExceptionClass() != null) {
|
||||
span.hasStatus(StatusData.error())
|
||||
.hasEventsSatisfyingExactly(
|
||||
event ->
|
||||
event
|
||||
.hasName("exception")
|
||||
.hasAttributesSatisfyingExactly(
|
||||
equalTo(
|
||||
ExceptionAttributes.EXCEPTION_TYPE,
|
||||
spanData.getExceptionClass().getCanonicalName()),
|
||||
satisfies(
|
||||
ExceptionAttributes.EXCEPTION_STACKTRACE,
|
||||
val -> val.isInstanceOf(String.class)),
|
||||
satisfies(
|
||||
ExceptionAttributes.EXCEPTION_MESSAGE,
|
||||
val -> val.isInstanceOf(String.class))));
|
||||
}
|
||||
|
||||
return span.hasName("Compile " + spanData.getRoute())
|
||||
.hasParent(spanData.getParent())
|
||||
.hasAttributesSatisfyingExactly(
|
||||
equalTo(stringKey("jsp.classFQCN"), "org.apache.jsp." + spanData.getClassName()),
|
||||
equalTo(stringKey("jsp.compiler"), "org.apache.jasper.compiler.JDTCompiler"));
|
||||
}
|
||||
|
||||
SpanDataAssert assertRenderSpan(SpanDataAssert span, JspSpan spanData) {
|
||||
String requestUrl = spanData.getRoute();
|
||||
if (spanData.getRequestUrlOverride() != null) {
|
||||
requestUrl = spanData.getRequestUrlOverride();
|
||||
}
|
||||
|
||||
if (spanData.getExceptionClass() != null) {
|
||||
span.hasStatus(StatusData.error())
|
||||
.hasEventsSatisfyingExactly(
|
||||
event ->
|
||||
event
|
||||
.hasName("exception")
|
||||
.hasAttributesSatisfyingExactly(
|
||||
satisfies(
|
||||
ExceptionAttributes.EXCEPTION_TYPE,
|
||||
val ->
|
||||
val.satisfiesAnyOf(
|
||||
v -> val.isEqualTo(spanData.getExceptionClass().getName()),
|
||||
v ->
|
||||
val.contains(
|
||||
spanData.getExceptionClass().getSimpleName()))),
|
||||
satisfies(
|
||||
ExceptionAttributes.EXCEPTION_MESSAGE,
|
||||
val ->
|
||||
val.satisfiesAnyOf(
|
||||
v -> assertThat(spanData.getErrorMessageOptional()).isTrue(),
|
||||
v -> val.isInstanceOf(String.class))),
|
||||
satisfies(
|
||||
ExceptionAttributes.EXCEPTION_STACKTRACE,
|
||||
val -> val.isInstanceOf(String.class))));
|
||||
}
|
||||
|
||||
return span.hasName("Render " + spanData.getRoute())
|
||||
.hasParent(spanData.getParent())
|
||||
.hasAttributesSatisfyingExactly(
|
||||
equalTo(stringKey("jsp.requestURL"), baseUrl + requestUrl),
|
||||
satisfies(
|
||||
stringKey("jsp.forwardOrigin"),
|
||||
val ->
|
||||
val.satisfiesAnyOf(
|
||||
v -> assertThat(spanData.getForwardOrigin()).isNull(),
|
||||
v -> assertThat(v).isEqualTo(spanData.getForwardOrigin()))));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue