Skip to content

Commit

Permalink
Azure Monitor Query: Migrate to test proxy (Azure#34542)
Browse files Browse the repository at this point in the history
* Azure Monitor Query: Migrate to test proxy

* add comment

* fix recording

* remove unused imports
  • Loading branch information
srnagar authored Apr 18, 2023
1 parent 65e6ed3 commit f80d779
Show file tree
Hide file tree
Showing 46 changed files with 56,466 additions and 1,229 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import com.azure.core.http.HttpClient;
import com.azure.core.http.policy.RetryPolicy;
import com.azure.core.http.policy.RetryStrategy;
import com.azure.core.test.TestBase;
import com.azure.core.test.TestMode;
import com.azure.core.test.TestProxyTestBase;
import com.azure.core.test.http.AssertingHttpClientBuilder;
import com.azure.core.util.Configuration;
import com.azure.core.util.Context;
Expand All @@ -23,9 +23,7 @@
import com.azure.monitor.query.models.LogsQueryResult;
import com.azure.monitor.query.models.LogsQueryResultStatus;
import com.azure.monitor.query.models.QueryTimeInterval;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable;
import reactor.core.publisher.Mono;
Expand All @@ -38,7 +36,6 @@
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Random;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
Expand All @@ -48,7 +45,7 @@
/**
* Unit tests for {@link LogsQueryAsyncClient}.
*/
public class LogsQueryAsyncClientTest extends TestBase {
public class LogsQueryAsyncClientTest extends TestProxyTestBase {

private static final String WORKSPACE_ID = Configuration.getGlobalConfiguration()
.get("AZURE_MONITOR_LOGS_WORKSPACE_ID", "d2d0e126-fa1e-4b0a-b647-250cdd471e68");
Expand Down Expand Up @@ -130,18 +127,12 @@ public void testLogsResourceQuery() {

@Test
public void testLogsQueryAllowPartialSuccess() {
Assumptions.assumeTrue(getTestMode() == TestMode.PLAYBACK,
"This test only executes in playback because the partial success condition requires pre-populated data.");

// Arrange
final String query = "AppTraces \n"
+ "| where Properties !has \"PartitionPumpManager\"\n"
+ "| where Properties has \"LoggerName\" and Properties has_cs \"com.azure\"\n"
+ "| project TimeGenerated, Message, Properties\n"
+ "| extend m = parse_json(Message)\n"
+ "| extend p = parse_json(Properties)\n"
+ " | project TimeGenerated, Thread=p.ThreadName, Logger=p.LoggerName, ConnectionId=m.connectionId, Message\n"
+ "\n";
final String query = "let dt = datatable (DateTime: datetime, Bool:bool, Guid: guid, Int: "
+ "int, Long:long, Double: double, String: string, Timespan: timespan, Decimal: decimal, Dynamic: dynamic)\n"
+ "[datetime(2015-12-31 23:59:59.9), false, guid(74be27de-1e4e-49d9-b579-fe0b331d3642), 12345, 1, 12345.6789,"
+ " 'string value', 10s, decimal(0.10101), dynamic({\"a\":123, \"b\":\"hello\", \"c\":[1,2,3], \"d\":{}})];"
+ "range x from 1 to 400000 step 1 | extend y=1 | join kind=fullouter dt on $left.y == $right.Long";

final LogsQueryOptions options = new LogsQueryOptions().setAllowPartialErrors(true);
final QueryTimeInterval interval = QueryTimeInterval.LAST_DAY;
Expand Down Expand Up @@ -314,13 +305,13 @@ public void testBatchStatistics() {
+ " not readily reproducible and because the service caches query results, the queries that require extended time "
+ "to complete if run the first time can return immediately if a cached result is available. So, this test can "
+ " wait for a long time before succeeding. So, disabling this in LIVE test mode")
@Disabled
public void testServerTimeout() {
// The server does not always stop processing the request and return a 504 before the client times out
// so, retry until a 504 response is returned
Random random = new Random();
// add some random number to circumvent cached response from server
long count = 1000000000000L + random.nextInt(10000);
// With test proxy migration, the request body is also recorded and the request has to match exactly for the
// recording to work. So, updating the exact count used to record the server timeout exception. When re-recording,
// add a random number to this to bypass the server from returning cached results.
long count = 1000000006959L;
// this query should take more than 5 seconds usually, but the server may have cached the
// response and may return before 5 seconds. So, retry with another query (different count value)
StepVerifier.create(client.queryWorkspaceWithResponse(WORKSPACE_ID, "range x from 1 to " + count + " "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
import com.azure.core.http.policy.RetryPolicy;
import com.azure.core.http.policy.RetryStrategy;
import com.azure.core.http.rest.Response;
import com.azure.core.test.TestBase;
import com.azure.core.test.TestMode;
import com.azure.core.test.TestProxyTestBase;
import com.azure.core.test.http.AssertingHttpClientBuilder;
import com.azure.core.util.Configuration;
import com.azure.core.util.Context;
Expand All @@ -24,7 +24,6 @@
import com.azure.monitor.query.models.LogsQueryResult;
import com.azure.monitor.query.models.LogsQueryResultStatus;
import com.azure.monitor.query.models.QueryTimeInterval;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable;
Expand All @@ -37,7 +36,6 @@
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Random;

import static com.azure.monitor.query.LogsQueryAsyncClientTest.RESOURCE_ID;
import static org.junit.jupiter.api.Assertions.assertEquals;
Expand All @@ -48,7 +46,7 @@
/**
* Unit tests for {@link LogsQueryClient}
*/
public class LogsQueryClientTest extends TestBase {
public class LogsQueryClientTest extends TestProxyTestBase {

private static final String WORKSPACE_ID = Configuration.getGlobalConfiguration()
.get("AZURE_MONITOR_LOGS_WORKSPACE_ID", "d2d0e126-fa1e-4b0a-b647-250cdd471e68");
Expand Down Expand Up @@ -121,18 +119,13 @@ public void testLogsQueryResource() {

@Test
public void testLogsQueryAllowPartialSuccess() {
Assumptions.assumeTrue(getTestMode() == TestMode.PLAYBACK,
"This test only executes in playback because the partial success condition requires pre-populated data.");

// Arrange
final String query = "AppTraces \n"
+ "| where Properties !has \"PartitionPumpManager\"\n"
+ "| where Properties has \"LoggerName\" and Properties has_cs \"com.azure\"\n"
+ "| project TimeGenerated, Message, Properties\n"
+ "| extend m = parse_json(Message)\n"
+ "| extend p = parse_json(Properties)\n"
+ " | project TimeGenerated, Thread=p.ThreadName, Logger=p.LoggerName, ConnectionId=m.connectionId, Message\n"
+ "\n";
final String query = "let dt = datatable (DateTime: datetime, Bool:bool, Guid: guid, Int: "
+ "int, Long:long, Double: double, String: string, Timespan: timespan, Decimal: decimal, Dynamic: dynamic)\n"
+ "[datetime(2015-12-31 23:59:59.9), false, guid(74be27de-1e4e-49d9-b579-fe0b331d3642), 12345, 1, 12345.6789,"
+ " 'string value', 10s, decimal(0.10101), dynamic({\"a\":123, \"b\":\"hello\", \"c\":[1,2,3], \"d\":{}})];"
+ "range x from 1 to 400000 step 1 | extend y=1 | join kind=fullouter dt on $left.y == $right.Long";

final LogsQueryOptions options = new LogsQueryOptions().setAllowPartialErrors(true);
final QueryTimeInterval interval = QueryTimeInterval.LAST_DAY;
Expand Down Expand Up @@ -290,10 +283,11 @@ public void testBatchStatistics() {
public void testServerTimeout() {
// The server does not always stop processing the request and return a 504 before the client times out
// so, retry until a 504 response is returned
Random random = new Random();
while (true) {
// add some random number to circumvent cached response from server
long count = 1000000000000L + random.nextInt(10000);
// With test proxy migration, the request body is also recorded and the request has to match exactly for the
// recording to work. So, updating the exact count used to record the server timeout exception. When re-recording,
// add a random number to this to bypass the server from returning cached results.
long count = 1000000007696L;
try {
// this query should take more than 5 seconds usually, but the server may have cached the
// response and may return before 5 seconds. So, retry with another query (different count value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import com.azure.core.credential.AccessToken;
import com.azure.core.credential.TokenCredential;
import com.azure.core.http.HttpClient;
import com.azure.core.test.TestBase;
import com.azure.core.test.TestMode;
import com.azure.core.test.TestProxyTestBase;
import com.azure.core.test.http.AssertingHttpClientBuilder;
import com.azure.core.util.Configuration;
import com.azure.core.util.Context;
Expand Down Expand Up @@ -42,7 +42,7 @@
/**
* Unit tests for {@link MetricsQueryAsyncClient}.
*/
public class MetricsQueryAsyncClientTest extends TestBase {
public class MetricsQueryAsyncClientTest extends TestProxyTestBase {
private static final String RESOURCE_URI = Configuration.getGlobalConfiguration()
.get("AZURE_MONITOR_METRICS_RESOURCE_URI",
"/subscriptions/faa080af-c1d8-40ad-9cce-e1a450ca5b57/resourceGroups/srnagar-azuresdkgroup/providers/Microsoft.CognitiveServices/accounts/srnagara-textanalytics");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
import com.azure.core.http.HttpClient;
import com.azure.core.http.rest.PagedIterable;
import com.azure.core.http.rest.Response;
import com.azure.core.test.TestBase;
import com.azure.core.test.TestMode;
import com.azure.core.test.TestProxyTestBase;
import com.azure.core.test.http.AssertingHttpClientBuilder;
import com.azure.core.util.Configuration;
import com.azure.core.util.Context;
Expand Down Expand Up @@ -44,7 +44,7 @@
/**
* Unit tests for {@link MetricsQueryClient}.
*/
public class MetricsQueryClientTest extends TestBase {
public class MetricsQueryClientTest extends TestProxyTestBase {
private static final String RESOURCE_URI = Configuration.getGlobalConfiguration()
.get("AZURE_MONITOR_METRICS_RESOURCE_URI",
"/subscriptions/faa080af-c1d8-40ad-9cce-e1a450ca5b57/resourceGroups/srnagar-azuresdkgroup/providers/Microsoft.CognitiveServices/accounts/srnagara-textanalytics");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,176 @@
{
"networkCallRecords" : [ {
"Method" : "POST",
"Uri" : "https://REDACTED.loganalytics.io/v1/$batch",
"Headers" : {
"User-Agent" : "azsdk-java-azure-monitor-query/1.2.0-beta.1 (17.0.2; Windows 11; 10.0)",
"x-ms-client-request-id" : "3d7f76cb-71e9-4837-930e-176eebc57741",
"Content-Type" : "application/json"
},
"Response" : {
"Transfer-Encoding" : "chunked",
"Access-Control-Allow-Origin" : "*",
"X-Content-Type-Options" : "nosniff",
"Connection" : "keep-alive",
"retry-after" : "0",
"StatusCode" : "200",
"Date" : "Tue, 14 Mar 2023 07:50:11 GMT",
"via" : "1.1 draft-oms-5979b88dcd-kx47g",
"Strict-Transport-Security" : "max-age=15724800; includeSubDomains",
"Access-Control-Expose-Headers" : "Retry-After,Age,WWW-Authenticate,x-resource-identities,x-ms-status-location",
"Vary" : "Accept-Encoding",
"Body" : "{\"responses\":[{\"id\":\"2\",\"status\":400,\"body\":{\"error\":{\"message\":\"The request had some invalid properties\",\"code\":\"BadArgumentError\",\"correlationId\":\"31269348-b3c4-4147-b79e-f1143ee64c0c\",\"innererror\":{\"code\":\"SyntaxError\",\"message\":\"A recognition error occurred in the query.\",\"innererror\":{\"code\":\"SYN0002\",\"message\":\"Query could not be parsed at '<EOF>' on line [2,299]\",\"line\":2,\"pos\":299,\"token\":\"<EOF>\"}}}}},{\"id\":\"1\",\"status\":200,\"body\":{\"tables\":[{\"name\":\"PrimaryResult\",\"columns\":[{\"name\":\"x\",\"type\":\"long\"},{\"name\":\"y\",\"type\":\"long\"},{\"name\":\"DateTime\",\"type\":\"datetime\"},{\"name\":\"Bool\",\"type\":\"bool\"},{\"name\":\"Guid\",\"type\":\"guid\"},{\"name\":\"Int\",\"type\":\"int\"},{\"name\":\"Long\",\"type\":\"long\"},{\"name\":\"Double\",\"type\":\"real\"},{\"name\":\"String\",\"type\":\"string\"},{\"name\":\"Timespan\",\"type\":\"timespan\"},{\"name\":\"Decimal\",\"type\":\"decimal\"},{\"name\":\"Dynamic\",\"type\":\"dynamic\"}],\"rows\":[[100,1,\"2015-12-31T23:59:59.9Z\",false,\"74be27de-1e4e-49d9-b579-fe0b331d3642\",12345,1,12345.6789,\"string value\",\"00:00:10\",\"0.10101\",\"{\\\"a\\\":123,\\\"b\\\":\\\"hello\\\",\\\"c\\\":[1,2,3],\\\"d\\\":{}}\"],[99,1,\"2015-12-31T23:59:59.9Z\",false,\"74be27de-1e4e-49d9-b579-fe0b331d3642\",12345,1,12345.6789,\"string value\",\"00:00:10\",\"0.10101\",\"{\\\"a\\\":123,\\\"b\\\":\\\"hello\\\",\\\"c\\\":[1,2,3],\\\"d\\\":{}}\"]]}]}}]}",
"Content-Type" : "application/json; charset=utf-8"
},
"Exception" : null
} ],
"variables" : [ ]
}
"Entries": [
{
"RequestUri": "https://REDACTED/v1/$batch",
"RequestMethod": "POST",
"RequestHeaders": {
"Accept": "application/json",
"Authorization": "Sanitized",
"Content-Length": "1234",
"Content-Type": "application/json",
"Date": "Tue, 18 Apr 2023 18:00:51 GMT",
"User-Agent": "azsdk-java-azure-monitor-query/1.2.0-beta.1 (17.0.2; Windows 11; 10.0)",
"x-ms-client-request-id": "e9551643-9abe-483b-af21-fb294d449a61"
},
"RequestBody": {
"requests": [
{
"id": "1",
"body": {
"query": "let dt = datatable (DateTime: datetime, Bool:bool, Guid: guid, Int: int, Long:long, Double: double, String: string, Timespan: timespan, Decimal: decimal, Dynamic: dynamic)\n[datetime(2015-12-31 23:59:59.9), false, guid(74be27de-1e4e-49d9-b579-fe0b331d3642), 12345, 1, 12345.6789, \u0027string value\u0027, 10s, decimal(0.10101), dynamic({\u0022a\u0022:123, \u0022b\u0022:\u0022hello\u0022, \u0022c\u0022:[1,2,3], \u0022d\u0022:{}})];range x from 1 to 100 step 1 | extend y=1 | join kind=fullouter dt on $left.y == $right.Long | take 2"
},
"workspace": "d2d0e126-fa1e-4b0a-b647-250cdd471e68",
"headers": {},
"path": "/query",
"method": "POST"
},
{
"id": "2",
"body": {
"query": "let dt = datatable (DateTime: datetime, Bool:bool, Guid: guid, Int: int, Long:long, Double: double, String: string, Timespan: timespan, Decimal: decimal, Dynamic: dynamic)\n[datetime(2015-12-31 23:59:59.9), false, guid(74be27de-1e4e-49d9-b579-fe0b331d3642), 12345, 1, 12345.6789, \u0027string value\u0027, 10s, decimal(0.10101), dynamic({\u0022a\u0022:123, \u0022b\u0022:\u0022hello\u0022, \u0022c\u0022:[1,2,3], \u0022d\u0022:{}})];range x from 1 to 100 step 1 | extend y=1 | join kind=fullouter dt on $left.y == $right.Long | take"
},
"workspace": "d2d0e126-fa1e-4b0a-b647-250cdd471e68",
"headers": {},
"path": "/query",
"method": "POST"
}
]
},
"StatusCode": 200,
"ResponseHeaders": {
"Access-Control-Allow-Origin": "*",
"Access-Control-Expose-Headers": "Retry-After,Age,WWW-Authenticate,x-resource-identities,x-ms-status-location",
"Connection": "keep-alive",
"Content-Type": "application/json; charset=utf-8",
"Date": "Tue, 18 Apr 2023 18:00:52 GMT",
"Strict-Transport-Security": "max-age=15724800; includeSubDomains",
"Transfer-Encoding": "chunked",
"Vary": "Accept-Encoding",
"Via": "1.1 draft-oms-666995cb46-22qw8",
"X-Content-Type-Options": "nosniff"
},
"ResponseBody": {
"responses": [
{
"id": "1",
"status": 200,
"headers": {
"Age": "91",
"request-context": "appId=cid-v1:70941e4f-7e8f-40b7-b730-183893db0297"
},
"body": {
"tables": [
{
"name": "PrimaryResult",
"columns": [
{
"name": "x",
"type": "long"
},
{
"name": "y",
"type": "long"
},
{
"name": "DateTime",
"type": "datetime"
},
{
"name": "Bool",
"type": "bool"
},
{
"name": "Guid",
"type": "guid"
},
{
"name": "Int",
"type": "int"
},
{
"name": "Long",
"type": "long"
},
{
"name": "Double",
"type": "real"
},
{
"name": "String",
"type": "string"
},
{
"name": "Timespan",
"type": "timespan"
},
{
"name": "Decimal",
"type": "decimal"
},
{
"name": "Dynamic",
"type": "dynamic"
}
],
"rows": [
[
100,
1,
"2015-12-31T23:59:59.9Z",
false,
"74be27de-1e4e-49d9-b579-fe0b331d3642",
12345,
1,
12345.6789,
"string value",
"00:00:10",
"0.10101",
"{\u0022a\u0022:123,\u0022b\u0022:\u0022hello\u0022,\u0022c\u0022:[1,2,3],\u0022d\u0022:{}}"
],
[
99,
1,
"2015-12-31T23:59:59.9Z",
false,
"74be27de-1e4e-49d9-b579-fe0b331d3642",
12345,
1,
12345.6789,
"string value",
"00:00:10",
"0.10101",
"{\u0022a\u0022:123,\u0022b\u0022:\u0022hello\u0022,\u0022c\u0022:[1,2,3],\u0022d\u0022:{}}"
]
]
}
]
}
},
{
"id": "2",
"status": 400,
"body": {
"error": {
"message": "The request had some invalid properties",
"code": "BadArgumentError",
"correlationId": "c6c594e9-2703-4738-80c2-3b6ba90316e3",
"innererror": {
"code": "SyntaxError",
"message": "A recognition error occurred in the query.",
"innererror": {
"code": "SYN0002",
"message": "Query could not be parsed at \u0027\u003CEOF\u003E\u0027 on line [2,299]",
"line": 2,
"pos": 299,
"token": "\u003CEOF\u003E"
}
}
}
}
}
]
}
}
],
"Variables": {}
}
Loading

0 comments on commit f80d779

Please sign in to comment.