25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * CDDL HEADER START
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * The contents of this file are subject to the terms of the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Common Development and Distribution License (the "License").
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * You may not use this file except in compliance with the License.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * or http://www.opensolaris.org/os/licensing.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * See the License for the specific language governing permissions
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * and limitations under the License.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * When distributing Covered Code, include this CDDL HEADER in each
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * If applicable, add the following below this CDDL HEADER, with the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * fields enclosed by brackets "[]" replaced with your own identifying
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * information: Portions Copyright [yyyy] [name of copyright owner]
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * CDDL HEADER END
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Use is subject to license terms.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlimport org.opensolaris.os.dtrace.*;
25cf1a301a396c38e8adf52c15f537b80d2483f7jlimport java.util.*;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/**
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Assert getAggregate() can explicitly specify the anonymous aggregation.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlpublic class TestGetAggregate {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl static final String programString =
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "profile:::tick-50ms" +
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "{" +
25cf1a301a396c38e8adf52c15f537b80d2483f7jl " @ = count();" +
25cf1a301a396c38e8adf52c15f537b80d2483f7jl " @a = count();" +
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "}";
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl static final String ANONYMOUS_AGGREGATION = "";
25cf1a301a396c38e8adf52c15f537b80d2483f7jl static final int TICK = 50;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl static final int EXPECTED_TICKS = 3;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl static final int INTERVALS = 4;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl static void
25cf1a301a396c38e8adf52c15f537b80d2483f7jl testIncluded(Consumer consumer, String ... aggregationNames)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl throws DTraceException, InterruptedException
25cf1a301a396c38e8adf52c15f537b80d2483f7jl {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Aggregate aggregate;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Set <String> included = new HashSet <String> ();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int n = 1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl for (String name : aggregationNames) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl included.add(name);
a192e900f6d2b0e1a822e3252c0dfd795ed49d76amaguire }
a192e900f6d2b0e1a822e3252c0dfd795ed49d76amaguire
// Wait up to a full second to obtain aggregate data. Without a
// time limit, we'll loop forever if no aggregation was
// successfully included.
do {
Thread.sleep(TICK);
aggregate = consumer.getAggregate(included, null);
} while (aggregate.asMap().isEmpty() && n++ < (1000 / TICK));
for (String name : included) {
if (aggregate.getAggregation(name) == null) {
throw new IllegalStateException("@" + name +
" was explicitly included but did not appear " +
"in the aggregate");
}
}
for (Aggregation a : aggregate.getAggregations()) {
if (!included.contains(a.getName())) {
throw new IllegalStateException("@" + a.getName() +
" was not explicitly included but appeared " +
"in the aggregate anyway");
}
}
if (!consumer.isRunning()) {
throw new IllegalStateException("consumer exited");
}
}
static void
testCleared(Consumer consumer, String ... aggregationNames)
throws DTraceException, InterruptedException
{
Aggregate aggregate;
AggregationRecord rec;
long value;
Long firstValue;
int n = 1;
Map <String, Long> firstValues = new HashMap <String, Long> ();
Set <String> cleared = new HashSet <String> ();
for (String name : aggregationNames) {
cleared.add(name);
}
do {
Thread.sleep(TICK);
aggregate = consumer.getAggregate(null, cleared);
} while (aggregate.asMap().isEmpty() && n++ < (1000 / TICK));
n = 1;
do {
Thread.sleep(TICK * EXPECTED_TICKS);
aggregate = consumer.getAggregate(null, cleared);
for (Aggregation a : aggregate.getAggregations()) {
if (!firstValues.containsKey(a.getName())) {
rec = a.getRecord(Tuple.EMPTY);
value = rec.getValue().getValue().longValue();
firstValues.put(a.getName(), value);
}
}
} while (consumer.isRunning() && n++ < INTERVALS);
for (Aggregation a : aggregate.getAggregations()) {
rec = a.getRecord(Tuple.EMPTY);
value = rec.getValue().getValue().longValue();
firstValue = firstValues.get(a.getName());
if (cleared.contains(a.getName())) {
// last value should be about the same as first value
if (value > (firstValue * 2)) {
throw new IllegalStateException(
"@" + a.getName() + " should have " +
"been cleared but instead grew from " +
firstValue + " to " + value);
}
} else {
// last value should be about (INTERVALS * firstValue)
if (value < (firstValue * 2)) {
throw new IllegalStateException(
"@" + a.getName() + " should have " +
"accumulated a running total but " +
"instead went from " +
firstValue + " to " + value);
}
}
}
if (!consumer.isRunning()) {
throw new IllegalStateException("consumer exited");
}
}
static Integer includedStatus;
static Integer clearedStatus;
static void
startIncludedTest()
{
final Consumer consumer = new LocalConsumer();
consumer.addConsumerListener(new ConsumerAdapter() {
public void consumerStarted(ConsumerEvent e) {
new Thread(new Runnable() {
public void run() {
try {
testIncluded(consumer, ANONYMOUS_AGGREGATION);
includedStatus = 0;
} catch (Exception e) {
includedStatus = 1;
e.printStackTrace();
} finally {
consumer.abort();
}
}
}).start();
}
});
try {
consumer.open();
consumer.setOption(Option.aggrate, Option.millis(TICK));
consumer.compile(programString);
consumer.enable();
consumer.go();
} catch (Exception e) {
includedStatus = 1;
e.printStackTrace();
}
}
static void
startClearedTest()
{
final Consumer consumer = new LocalConsumer();
consumer.addConsumerListener(new ConsumerAdapter() {
public void consumerStarted(ConsumerEvent e) {
new Thread(new Runnable() {
public void run() {
try {
testCleared(consumer, ANONYMOUS_AGGREGATION);
clearedStatus = 0;
} catch (Exception e) {
clearedStatus = 1;
e.printStackTrace();
} finally {
consumer.abort();
}
}
}).start();
}
});
try {
consumer.open();
consumer.setOption(Option.aggrate, Option.millis(TICK));
consumer.compile(programString);
consumer.enable();
consumer.go();
} catch (Exception e) {
clearedStatus = 1;
e.printStackTrace();
}
}
public static void
main(String[] args)
{
startIncludedTest();
do {
try {
Thread.sleep(TICK);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (includedStatus == null);
startClearedTest();
do {
try {
Thread.sleep(TICK);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (clearedStatus == null);
if (includedStatus != 0 || clearedStatus != 0) {
System.out.println("Failure");
System.exit(1);
}
System.out.println("Success");
}
}