Skip to content

Commit

Permalink
Add integration testing for latency instrumentation
Browse files Browse the repository at this point in the history
Adds a thorough integration test which tests latency instrumentation by querying
a resource which makes a downstream call to itself, recording timing info along
the way. This timing info is checked for completeness and consistency.

RB=1745931
G=sf-reviewers
R=fcapponi,ssheng,crzhang,bsoetarm,dmessink
A=kbalasub,crzhang,bsoetarm
  • Loading branch information
evanw555 committed Dec 10, 2019
1 parent 67c7ebd commit 6fc9d37
Show file tree
Hide file tree
Showing 15 changed files with 933 additions and 23 deletions.
10 changes: 8 additions & 2 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
28.0.13
-------
28.1.1
------

28.1.0
------
(RB=1745931)
Add integration testing for latency instrumentation

(RB=1745924)
Add instrumentation timing markers for projection mask application

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version=28.0.12
version=28.1.0
sonatypeUsername=please_set_in_home_dir_if_uploading_to_maven_central
sonatypePassword=please_set_in_home_dir_if_uploading_to_maven_central
org.gradle.configureondemand=true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name" : "latencyInstrumentation",
"namespace" : "com.linkedin.restli.examples.instrumentation.client",
"path" : "/latencyInstrumentation",
"schema" : "com.linkedin.restli.examples.instrumentation.api.InstrumentationControl",
"doc" : "Resource used for testing framework latency instrumentation.\n\n The integration test using this resource queries {@link #create(InstrumentationControl)} (the \"upstream endpoint\"),\n which queries {@link #batchPartialUpdate(BatchPatchRequest)} (the \"downstream endpoint\"). The \"upstream endpoint\"\n collects all the client-side timing data after the downstream call has completed and packs it into the original\n server-side request context so that the integration test has access to all of it.\n\n The input entity itself indicates to the resource whether to use streaming or rest, whether to throw an exception at\n both endpoints, whether to use scatter-gather for the downstream request, and what its own hostname is so it can make\n the circular downstream request. The \"upstream endpoint\" sets a special header so that the integration test knows\n which request to analyze, this is done to avoid analyzing the protocol version fetch request.\n\ngenerated from: com.linkedin.restli.examples.instrumentation.server.LatencyInstrumentationResource",
"collection" : {
"identifier" : {
"name" : "latencyInstrumentationId",
"type" : "long"
},
"supports" : [ "batch_partial_update", "create" ],
"methods" : [ {
"annotations" : {
"returnEntity" : { }
},
"method" : "create",
"doc" : "This is the \"upstream endpoint\" which is queried directly by the integration test.\n This endpoint makes a call to {@link #batchPartialUpdate(BatchPatchRequest)} (the \"downstream endpoint\"),\n then packs all the client-side timing data into the original server-side request context."
}, {
"annotations" : {
"returnEntity" : { }
},
"method" : "batch_partial_update",
"doc" : "This is the \"downstream endpoint\", queried by {@link #create(InstrumentationControl)} (the \"upstream endpoint\")."
} ],
"entity" : {
"path" : "/latencyInstrumentation/{latencyInstrumentationId}"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"type" : "record",
"name" : "InstrumentationControl",
"namespace" : "com.linkedin.restli.examples.instrumentation.api",
"doc" : "A record containing control information for latency instrumentation testing.",
"fields" : [
{
"name" : "serviceUriPrefix",
"type" : "string",
"doc" : "URI prefix of the service running the instrumentation resource."
},
{
"name" : "useStreaming",
"type" : "boolean",
"doc" : "Whether the resource should use streaming for its downstream service calls."
},
{
"name" : "forceException",
"type" : "boolean",
"doc" : "Whether the resource should throw service exceptions."
},
{
"name" : "useScatterGather",
"type" : "boolean",
"doc" : "Whether the resource should use scatter-gather for its downstream service calls."
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,17 @@
}
},
"java" : {
"coercerClass" : "com.linkedin.restli.examples.custom.types.CustomNonNegativeLongCoercer",
"class" : "com.linkedin.restli.examples.custom.types.CustomNonNegativeLong"
"class" : "com.linkedin.restli.examples.custom.types.CustomNonNegativeLong",
"coercerClass" : "com.linkedin.restli.examples.custom.types.CustomNonNegativeLongCoercer"
}
}, {
"type" : "typeref",
"name" : "DateRef",
"namespace" : "com.linkedin.restli.examples.typeref.api",
"ref" : "long",
"java" : {
"coercerClass" : "com.linkedin.restli.examples.custom.types.DateCoercer",
"class" : "java.util.Date"
"class" : "java.util.Date",
"coercerClass" : "com.linkedin.restli.examples.custom.types.DateCoercer"
}
} ],
"schema" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
"namespace" : "com.linkedin.restli.examples.typeref.api",
"ref" : "int",
"java" : {
"coercerClass" : "com.linkedin.restli.examples.custom.types.CalendarCoercer",
"class" : "java.util.Calendar"
"class" : "java.util.Calendar",
"coercerClass" : "com.linkedin.restli.examples.custom.types.CalendarCoercer"
}
}, {
"type" : "typeref",
Expand All @@ -50,17 +50,17 @@
"namespace" : "com.linkedin.restli.examples.typeref.api",
"ref" : "long",
"java" : {
"coercerClass" : "com.linkedin.restli.examples.custom.types.DateCoercer",
"class" : "java.util.Date"
"class" : "java.util.Date",
"coercerClass" : "com.linkedin.restli.examples.custom.types.DateCoercer"
}
}, {
"type" : "typeref",
"name" : "IPAddressSimple",
"namespace" : "com.linkedin.restli.examples.typeref.api",
"ref" : "bytes",
"java" : {
"coercerClass" : "com.linkedin.restli.examples.custom.types.IPAddressSimpleCoercer",
"class" : "java.net.InetAddress"
"class" : "java.net.InetAddress",
"coercerClass" : "com.linkedin.restli.examples.custom.types.IPAddressSimpleCoercer"
}
} ],
"schema" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
"namespace" : "com.linkedin.restli.examples.typeref.api",
"ref" : "long",
"java" : {
"coercerClass" : "com.linkedin.restli.examples.custom.types.DateCoercer",
"class" : "java.util.Date"
"class" : "java.util.Date",
"coercerClass" : "com.linkedin.restli.examples.custom.types.DateCoercer"
}
} ],
"schema" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
"namespace" : "com.linkedin.restli.examples.typeref.api",
"ref" : "string",
"java" : {
"coercerClass" : "com.linkedin.restli.examples.custom.types.UriCoercer",
"class" : "java.net.URI"
"class" : "java.net.URI",
"coercerClass" : "com.linkedin.restli.examples.custom.types.UriCoercer"
}
} ],
"schema" : {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"models" : [ {
"type" : "record",
"name" : "InstrumentationControl",
"namespace" : "com.linkedin.restli.examples.instrumentation.api",
"doc" : "A record containing control information for latency instrumentation testing.",
"fields" : [ {
"name" : "serviceUriPrefix",
"type" : "string",
"doc" : "URI prefix of the service running the instrumentation resource."
}, {
"name" : "useStreaming",
"type" : "boolean",
"doc" : "Whether the resource should use streaming for its downstream service calls."
}, {
"name" : "forceException",
"type" : "boolean",
"doc" : "Whether the resource should throw service exceptions."
}, {
"name" : "useScatterGather",
"type" : "boolean",
"doc" : "Whether the resource should use scatter-gather for its downstream service calls."
} ]
} ],
"schema" : {
"name" : "latencyInstrumentation",
"namespace" : "com.linkedin.restli.examples.instrumentation.client",
"path" : "/latencyInstrumentation",
"schema" : "com.linkedin.restli.examples.instrumentation.api.InstrumentationControl",
"doc" : "Resource used for testing framework latency instrumentation.\n\n The integration test using this resource queries {@link #create(InstrumentationControl)} (the \"upstream endpoint\"),\n which queries {@link #batchPartialUpdate(BatchPatchRequest)} (the \"downstream endpoint\"). The \"upstream endpoint\"\n collects all the client-side timing data after the downstream call has completed and packs it into the original\n server-side request context so that the integration test has access to all of it.\n\n The input entity itself indicates to the resource whether to use streaming or rest, whether to throw an exception at\n both endpoints, whether to use scatter-gather for the downstream request, and what its own hostname is so it can make\n the circular downstream request. The \"upstream endpoint\" sets a special header so that the integration test knows\n which request to analyze, this is done to avoid analyzing the protocol version fetch request.\n\ngenerated from: com.linkedin.restli.examples.instrumentation.server.LatencyInstrumentationResource",
"collection" : {
"identifier" : {
"name" : "latencyInstrumentationId",
"type" : "long"
},
"supports" : [ "batch_partial_update", "create" ],
"methods" : [ {
"annotations" : {
"returnEntity" : { }
},
"method" : "create",
"doc" : "This is the \"upstream endpoint\" which is queried directly by the integration test.\n This endpoint makes a call to {@link #batchPartialUpdate(BatchPatchRequest)} (the \"downstream endpoint\"),\n then packs all the client-side timing data into the original server-side request context."
}, {
"annotations" : {
"returnEntity" : { }
},
"method" : "batch_partial_update",
"doc" : "This is the \"downstream endpoint\", queried by {@link #create(InstrumentationControl)} (the \"upstream endpoint\")."
} ],
"entity" : {
"path" : "/latencyInstrumentation/{latencyInstrumentationId}"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
}
},
"java" : {
"coercerClass" : "com.linkedin.restli.examples.custom.types.CustomNonNegativeLongCoercer",
"class" : "com.linkedin.restli.examples.custom.types.CustomNonNegativeLong"
"class" : "com.linkedin.restli.examples.custom.types.CustomNonNegativeLong",
"coercerClass" : "com.linkedin.restli.examples.custom.types.CustomNonNegativeLongCoercer"
}
}, {
"type" : "typeref",
Expand Down
2 changes: 2 additions & 0 deletions restli-int-test-server/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ apply plugin: 'java'
dependencies {
compile project(':restli-int-test-api')
compile project(path: ':restli-int-test-api', configuration: 'dataTemplate')
compile project(path: ':restli-int-test-api', configuration: 'restClient')
compile project(':restli-server-standalone') // for task startServerStandaloneLauncher
compile project(':data')
compile project(':data-testutils')
Expand Down Expand Up @@ -118,6 +119,7 @@ clean.dependsOn(cleanGenerateGreetings)
// Generate IDLs for ACL, Groups, and Greetings.
pegasus.main.idlOptions.addIdlItem(['com.linkedin.restli.examples.groups.server'])
pegasus.main.idlOptions.addIdlItem(['com.linkedin.restli.examples.greetings.server'])
pegasus.main.idlOptions.addIdlItem(['com.linkedin.restli.examples.instrumentation.server'])
pegasus.main.idlOptions.addIdlItem(['com.linkedin.restli.examples.typeref.server'])
pegasus.test.idlOptions.addIdlItem(['com.linkedin.restli.restspec'])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public class RestLiIntTestServer
public static final String[] RESOURCE_PACKAGE_NAMES = {
"com.linkedin.restli.examples.groups.server.rest.impl",
"com.linkedin.restli.examples.greetings.server",
"com.linkedin.restli.examples.instrumentation.server",
"com.linkedin.restli.examples.typeref.server" };

public static void main(String[] args) throws IOException
Expand Down
Loading

0 comments on commit 6fc9d37

Please sign in to comment.