Java 用 Azure Load Testing クライアント ライブラリ - バージョン 1.0.7

Azure Load Testing は、ユーザーが Azure Load Testing サービスとネイティブに対話できる Java のクライアント ライブラリを提供します。 Azure Load Testing は、大規模な負荷を生成できるフル マネージドのロード テスト サービスです。 サービスは、アプリケーションがどこにホストされているかにかかわらず、そのトラフィックをシミュレートします。 開発者、テスト担当者、品質保証 (QA) エンジニアは、それを使用して、アプリケーションのパフォーマンス、スケーラビリティ、または容量を最適化できます

このパッケージには、Microsoft Azure Developer LoadTesting クライアント ライブラリが含まれています。

ドキュメント

作業の開始に役立つさまざまなドキュメントが用意されています

作業の開始

前提条件

製品へのパッケージの追加

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-developer-loadtesting</artifactId>
    <version>1.0.7</version>
</dependency>

認証

Azure Identity パッケージは、クライアントを認証するための既定の実装を提供します。

既定では、Azure Active Directory トークン認証は、次の環境変数の正しい構成に依存します。

  • AZURE_CLIENT_ID Azure クライアント ID の場合。
  • AZURE_TENANT_ID Azure テナント ID の場合。
  • AZURE_CLIENT_SECRET クライアント シークレットまたは AZURE_CLIENT_CERTIFICATE_PATH クライアント証明書の場合は 。

さらに、Azure サブスクリプション ID は環境変数 AZURE_SUBSCRIPTION_IDを使用して構成できます。

上記の構成では、 azure 次のコードを使用してクライアントを認証できます。

// ensure the user, service principal or managed identity used has Loadtesting Contributor role for the resource
TokenCredential credential = new DefaultAzureCredentialBuilder()
    .build();
// create client using DefaultAzureCredential
LoadTestAdministrationClient adminClient = new LoadTestAdministrationClientBuilder()
        .credential(credential)
        .endpoint("<Enter Azure Load Testing Data-Plane URL>")
        .buildClient();
LoadTestRunClient testRunClient = new LoadTestRunClientBuilder()
        .credential(credential)
        .endpoint("<Enter Azure Load Testing Data-Plane URL>")
        .buildClient();

RequestOptions reqOpts = new RequestOptions()
    .addQueryParam("orderBy", "lastModifiedDateTime")
    .addQueryParam("maxPageSize", "10");
adminClient.listTests(reqOpts);

reqOpts = new RequestOptions()
    .addQueryParam("orderBy", "lastModifiedDateTime")
    .addQueryParam("status", "EXECUTING,DONE")
    .addQueryParam("maxPageSize", "10");
testRunClient.listTestRuns(reqOpts);

主要な概念

次のコンポーネントは、Azure Load Testing サービスを構成します。 Java 用 Azure Load Test クライアント ライブラリを使用すると、クライアントを使用してこれらの各コンポーネントと対話できます。 ライブラリのメインエントリ ポイントである 2 つの最上位クライアントがあります

  • LoadTestingClient

  • LoadTestingAsyncClient

非同期クライアントのメソッドも非同期である点を除き、2 つのクライアントにも同様のメソッドがあります。

最上位クライアントには 2 つのサブクライアントがあります

  • LoadTestAdministration

  • TestRun

これらのサブクライアントは、サービスのさまざまなコンポーネントの管理と使用に使用されます。

ロード テスト管理クライアント

LoadTestAdministrationサブクライアントは、ロード テスト、アプリ コンポーネント、メトリックの管理と構成に使用されます。

テスト

テストでは、テスト スクリプトと、ロード テストを実行するための構成設定を指定します。 Azure Load Testing リソースに 1 つ以上のテストを作成できます。

アプリ コンポーネント

Azure でホストされるアプリケーションに対してロード テストを実行すると、さまざまな Azure アプリケーション コンポーネント (サーバー側のメトリック) のリソース メトリックを監視できます。 ロード テストの実行中、そしてテストの完了後に、Azure Load Testing ダッシュボードでリソース メトリックを監視および分析できます。

メトリック

ロード テストでは、Azure Load Testing によってテストの実行に関するメトリックが収集されます。 メトリックには、次の 2 種類があります。

  1. クライアント側のメトリックでは、テスト エンジンによって報告された詳細が表示されます。 これらのメトリックには、仮想ユーザーの数、要求の応答時間、失敗した要求の数、1 秒あたりの要求数が含まれます。

  2. Azure でホストされるアプリケーションでは、サーバー側のメトリックを使用して、Azure アプリケーション コンポーネントに関する情報を提供できます。 メトリックは、データベースの読み取りの数、HTTP 応答の種類、またはコンテナー リソースの消費量に対して指定できます。

テスト実行クライアント

TestRunサブクライアントは、ロード テストに対応するテスト実行の開始と停止に使用されます。 テストの実行は、1 回のロード テストの実行を表します。 Apache JMeter スクリプトの実行に関連付けられているログ、ロード テストの YAML 構成、監視するアプリ コンポーネントの一覧、テストの結果を収集します。

Data-Plane エンドポイント

Azure Load Testing リソースのデータ プレーンは、次の URL 形式を使用してアドレス指定できます。

00000000-0000-0000-0000-000000000000.aaa.cnt-prod.loadtesting.azure.com

最初の GUID 00000000-0000-0000-0000-000000000000 は、Azure Load Testing リソースへのアクセスに使用される一意の識別子です。 その後に、リソースの Azure リージョンが続きます aaa

データ プレーン エンドポイントは、コントロール プレーン API から取得されます。

例:1234abcd-12ab-12ab-12ab-123456abcdef.eus.cnt-prod.loadtesting.azure.com

上記の例では、 eus は Azure リージョン East USを表しています。

ロード テストの作成

LoadTestAdministrationClient adminClient = new LoadTestAdministrationClientBuilder()
        .credential(new DefaultAzureCredentialBuilder().build())
        .endpoint("<endpoint>")
        .buildClient();

// construct Test object using nested String:Object Maps
Map<String, Object> testMap = new HashMap<String, Object>();
testMap.put("displayName", "Sample Display Name");
testMap.put("description", "Sample Description");

// loadTestConfig describes the number of test engines to generate load
Map<String, Object> loadTestConfigMap = new HashMap<String, Object>();
loadTestConfigMap.put("engineInstances", 1);
testMap.put("loadTestConfiguration", loadTestConfigMap);

// environmentVariables are plain-text data passed to test engines
Map<String, Object> envVarMap = new HashMap<String, Object>();
envVarMap.put("a", "b");
envVarMap.put("x", "y");
testMap.put("environmentVariables", envVarMap);

// secrets are secure data sent using Azure Key Vault
Map<String, Object> secretMap = new HashMap<String, Object>();
Map<String, Object> sampleSecretMap = new HashMap<String, Object>();
sampleSecretMap.put("value", "https://samplevault.vault.azure.net/secrets/samplesecret/f113f91fd4c44a368049849c164db827");
sampleSecretMap.put("type", "AKV_SECRET_URI");
secretMap.put("sampleSecret", sampleSecretMap);
testMap.put("secrets", secretMap);

// passFailCriteria define the conditions to conclude the test as success
Map<String, Object> passFailMap = new HashMap<String, Object>();
Map<String, Object> passFailMetrics = new HashMap<String, Object>();
Map<String, Object> samplePassFailMetric = new HashMap<String, Object>();
samplePassFailMetric.put("clientmetric", "response_time_ms");
samplePassFailMetric.put("aggregate", "percentage");
samplePassFailMetric.put("condition", ">");
samplePassFailMetric.put("value", "20");
samplePassFailMetric.put("action", "continue");
passFailMetrics.put("fefd759d-7fe8-4f83-8b6d-aeebe0f491fe", samplePassFailMetric);
passFailMap.put("passFailMetrics", passFailMetrics);
testMap.put("passFailCriteria", passFailMap);

// convert the object Map to JSON BinaryData
BinaryData test = BinaryData.fromObject(testMap);

// receive response with BinaryData content
Response<BinaryData> testOutResponse = adminClient.createOrUpdateTestWithResponse("test12345", test, null);
System.out.println(testOutResponse.getValue().toString());

ロード テストへの .jmx ファイルのアップロード

LoadTestAdministrationClient adminClient = new LoadTestAdministrationClientBuilder()
    .credential(new DefaultAzureCredentialBuilder().build())
    .endpoint("<endpoint>")
    .buildClient();

// extract file contents to BinaryData
BinaryData fileData = BinaryData.fromFile(new File("path/to/file").toPath());

// receive response with BinaryData content
Response<BinaryData> fileUrlOut = adminClient.uploadTestFileWithResponse("test12345", "sample-file.jmx", fileData, null);
System.out.println(fileUrlOut.getValue().toString());

ロード テストの実行

LoadTestRunClient testRunClient = new LoadTestRunClientBuilder()
    .credential(new DefaultAzureCredentialBuilder().build())
    .endpoint("<endpoint>")
    .buildClient();

// construct Test Run object using nested String:Object Maps
Map<String, Object> testRunMap = new HashMap<String, Object>();
testRunMap.put("testId", "test12345");
testRunMap.put("displayName", "SDK-Created-TestRun");

// convert the object Map to JSON BinaryData
BinaryData testRun = BinaryData.fromObject(testRunMap);

// start test with poller
SyncPoller<BinaryData, BinaryData> poller = testRunClient.beginTestRun("testrun12345", testRun, null);
Duration pollInterval = Duration.ofSeconds(5);
poller = poller.setPollInterval(pollInterval);

// wait for test to reach terminal state
JsonNode testRunJson = null;
String testStatus;
PollResponse<BinaryData> pollResponse = poller.poll();
while (pollResponse.getStatus() == LongRunningOperationStatus.IN_PROGRESS || pollResponse.getStatus() == LongRunningOperationStatus.NOT_STARTED) {
    try {
        testRunJson = new ObjectMapper().readTree(pollResponse.getValue().toString());
        testStatus = testRunJson.get("status").asText();
        System.out.println("Test run status: " + testStatus);
    } catch (JsonProcessingException e) {
        System.out.println("Error processing JSON response");
        // handle error condition
    }

    // wait and check test status every 5 seconds
    try {
        Thread.sleep(pollInterval.toMillis());
    } catch (InterruptedException e) {
        // handle interruption
    }

    pollResponse = poller.poll();
}

poller.waitForCompletion();
BinaryData testRunBinary = poller.getFinalResult();
try {
    testRunJson = new ObjectMapper().readTree(testRunBinary.toString());
    testStatus = testRunJson.get("status").asText();
} catch (JsonProcessingException e) {
    System.out.println("Error processing JSON response");
    // handle error condition
}

String startDateTime = testRunJson.get("startDateTime").asText();
String endDateTime = testRunJson.get("endDateTime").asText();

// get list of all metric namespaces and pick the first one
Response<BinaryData> metricNamespacesOut = testRunClient.getMetricNamespacesWithResponse("testrun12345", null);
String metricNamespace = null;
// parse JSON and read first value
try {
    JsonNode metricNamespacesJson = new ObjectMapper().readTree(metricNamespacesOut.getValue().toString());
    metricNamespace = metricNamespacesJson.get("value").get(0).get("metricNamespaceName").asText();
} catch (JsonProcessingException e) {
    System.out.println("Error processing JSON response");
    // handle error condition
}

// get list of all metric definitions and pick the first one
Response<BinaryData> metricDefinitionsOut = testRunClient.getMetricDefinitionsWithResponse("testrun12345", metricNamespace, null);
String metricName = null;
// parse JSON and read first value
try {
    JsonNode metricDefinitionsJson = new ObjectMapper().readTree(metricDefinitionsOut.getValue().toString());
    metricName = metricDefinitionsJson.get("value").get(0).get("name").get("value").asText();
} catch (JsonProcessingException e) {
    System.out.println("Error processing JSON response");
    // handle error condition
}

// fetch client metrics using metric namespace and metric name
PagedIterable<BinaryData> clientMetricsOut = testRunClient.listMetrics("testrun12345", metricName, metricNamespace, startDateTime + '/' + endDateTime, null);
clientMetricsOut.forEach((clientMetric) -> {
    System.out.println(clientMetric.toString());
});

トラブルシューティング

Azure SDK for Java には、アプリケーション エラーのトラブルシューティングと解決の迅速化に役立つ一貫したログ記録のストーリーが用意されています。 生成されたログでは、最終状態に達する前のアプリケーションのフローがキャプチャされ、根本原因を特定するのに役立ちます。 ログ記録の有効化に関するガイダンスについては、ログ Wiki を参照してください。

次の手順

Azure Loading Testing Java SDK サンプルは、SDK の GitHub リポジトリで入手できます。 これらのサンプルでは、一般的に発生するその他のシナリオのコード例を示します。 「Azure Load Testing のサンプル」を参照してください。

共同作成

このリポジトリへの投稿の詳細については、 投稿ガイドを参照してください。

  1. フォークする
  2. 機能ブランチを作成する (git checkout -b my-new-feature)
  3. 変更をコミットする (git commit -am 'Add some feature')
  4. ブランチにプッシュする (git push origin my-new-feature)
  5. 新しい Pull Request を作成する