レポートへのカスタム・カウンターの追加

特定要件をモニターする場合、カスタム・コードを使用して、カスタム・カウンターをパフォーマンス・レポートに追加できます。 テストを実行した後、カスタム・カウンターからの結果は、デフォルトのパフォーマンス・テスト・カウンターと同じ方法で自動的に集約されます。

10.1.0 以降、カスタム・コードがテスト実行で開始されたときに、カスタム・コードによって生成されたカウンター情報をグラフで表示してモニターできるようになりました。

テストの実行後、カスタム・カウンターをレポートで表示できます。 カスタム・レポートを作成することで、別のページでもカスタム・カウンター情報を参照できます。 レポートのカスタマイズについて詳しくは、関連リンクを参照してください。

テスト実行サービス・インターフェースおよびクラスのJavadocには、Java API 解説書からアクセスできます。

以下のカスタム・コードをテストに追加して、レポートにカスタム・カウンターを作成できます。

package test;

import org.eclipse.hyades.test.common.event.VerdictEvent;

import com.ibm.rational.test.lt.kernel.services.ITestExecutionServices;
import com.ibm.rational.test.lt.kernel.services.stats.CountAggregationLevel;
import com.ibm.rational.test.lt.kernel.services.stats.CounterUnits;
import com.ibm.rational.test.lt.kernel.services.stats.ICounterFolder;
import com.ibm.rational.test.lt.kernel.services.stats.ICounterRegistry;
import com.ibm.rational.test.lt.kernel.services.stats.IStatisticsManager2;
import com.ibm.rational.test.lt.kernel.services.stats.IValueCounter;
import com.ibm.rational.test.lt.kernel.services.stats.ValueAggregationLevel;

import database.DatabaseAccess;
import database.TransactionResult;

public class DatabaseStats implements com.ibm.rational.test.lt.kernel.custom.ICustomCode2 {

	private static boolean registerDone;
	
	/**
	 * This method declares the counters that will be produced during execution.
	 * Declaring counters is optional, but it allows to customize some of their
	 * attributes, such as the label and unit, and what level of statistical information
	 * will be available in reports.
	 */
	private static synchronized void registerCounters(ICounterRegistry registry) {
		if (registerDone) return;
		registry.path("Database", "Transaction", "Attempts")
			.count()
			.aggregationLevel(CountAggregationLevel.RATE_RANGE)
			.label("Started Transactions")
			.unit("transactions")
			.register();
		
		registry.path("Database", "Transaction", "Commits")
			.verificationPoint()
			.label("Transaction Commits VP")
			.register();
		
		registry.path("Database", "Transaction", "Response Time", "Network")
			.value()
			.aggregationLevel(ValueAggregationLevel.RANGE)
			.unit(CounterUnits.MILLISECONDS)
			.register();
			
		registry.path("Database", "Transaction", "Response Time", "Commit")
			.value()
			.aggregationLevel(ValueAggregationLevel.DISTRIBUTION)
			.unit(CounterUnits.MILLISECONDS)
			.register();
		
		registry.path("Database", "Error")
			.text()
			.label("Database Error Message")
			.register();
		registerDone = true;
	}
	
	private DatabaseAccess database = DatabaseAccess.INSTANCE;
	
	/**
	 * This custom code adds a record in database. It produces a couple of counters,
	 * such as the database transaction attempts, successes/failures, and response time.
	 */
	public String exec(ITestExecutionServices tes, String[] args) {
		String product = args.length> 0 ? args[0] : "Default";
		IStatisticsManager2 mgr = tes.getStatisticsManager2();
		registerCounters(mgr.registry());
		
		database.startTransaction();
		mgr.getCountCounter("Database", "Transaction", "Attempts").increment();

		database.executeQuery("INSERT INTO TABLE Purchases VALUES('" + product + "', 1000)");
		TransactionResult result = database.commit();
		
		mgr.getVerificationPointCounter("Database", "Transaction", "Commits")
			.increment(result.isSuccess() ? VerdictEvent.VERDICT_PASS : VerdictEvent.VERDICT_FAIL);
		if (!result.isSuccess()) {
			mgr.getTextCounter("Database", "Error").addMeasurement(result.getErrorMessage());
		}
		
		ICounterFolder times = mgr.getFolder("Database", "Transaction", "Response Time");
		times.getValueCounter("Network").addMeasurement(result.getNetworkTime());
		times.getValueCounter("Commit").addMeasurement(result.getCommitTime());
		
		IValueCounter value = tes.getStatisticsManager2().getValueCounter("MyStats", "Value");
		value.addMeasurement(System.nanoTime() % 2000);
		
		return null;
	}

}