1*3e359d9cSTom Erickson /*
2*3e359d9cSTom Erickson  * CDDL HEADER START
3*3e359d9cSTom Erickson  *
4*3e359d9cSTom Erickson  * The contents of this file are subject to the terms of the
5*3e359d9cSTom Erickson  * Common Development and Distribution License (the "License").
6*3e359d9cSTom Erickson  * You may not use this file except in compliance with the License.
7*3e359d9cSTom Erickson  *
8*3e359d9cSTom Erickson  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*3e359d9cSTom Erickson  * or http://www.opensolaris.org/os/licensing.
10*3e359d9cSTom Erickson  * See the License for the specific language governing permissions
11*3e359d9cSTom Erickson  * and limitations under the License.
12*3e359d9cSTom Erickson  *
13*3e359d9cSTom Erickson  * When distributing Covered Code, include this CDDL HEADER in each
14*3e359d9cSTom Erickson  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*3e359d9cSTom Erickson  * If applicable, add the following below this CDDL HEADER, with the
16*3e359d9cSTom Erickson  * fields enclosed by brackets "[]" replaced with your own identifying
17*3e359d9cSTom Erickson  * information: Portions Copyright [yyyy] [name of copyright owner]
18*3e359d9cSTom Erickson  *
19*3e359d9cSTom Erickson  * CDDL HEADER END
20*3e359d9cSTom Erickson  */
21*3e359d9cSTom Erickson 
22*3e359d9cSTom Erickson /*
23*3e359d9cSTom Erickson  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24*3e359d9cSTom Erickson  * Use is subject to license terms.
25*3e359d9cSTom Erickson  */
26*3e359d9cSTom Erickson 
27*3e359d9cSTom Erickson import org.opensolaris.os.dtrace.*;
28*3e359d9cSTom Erickson import java.util.*;
29*3e359d9cSTom Erickson 
30*3e359d9cSTom Erickson /**
31*3e359d9cSTom Erickson  * Assert getAggregate() can explicitly specify the anonymous aggregation.
32*3e359d9cSTom Erickson  */
33*3e359d9cSTom Erickson public class TestGetAggregate {
34*3e359d9cSTom Erickson     static final String programString =
35*3e359d9cSTom Erickson 	    "profile:::tick-50ms" +
36*3e359d9cSTom Erickson 	    "{" +
37*3e359d9cSTom Erickson 	    "        @ = count();" +
38*3e359d9cSTom Erickson 	    "        @a = count();" +
39*3e359d9cSTom Erickson 	    "}";
40*3e359d9cSTom Erickson 
41*3e359d9cSTom Erickson     static final String ANONYMOUS_AGGREGATION = "";
42*3e359d9cSTom Erickson     static final int TICK = 50;
43*3e359d9cSTom Erickson     static final int EXPECTED_TICKS = 3;
44*3e359d9cSTom Erickson     static final int INTERVALS = 4;
45*3e359d9cSTom Erickson 
46*3e359d9cSTom Erickson     static void
testIncluded(Consumer consumer, String ... aggregationNames)47*3e359d9cSTom Erickson     testIncluded(Consumer consumer, String ... aggregationNames)
48*3e359d9cSTom Erickson 	    throws DTraceException, InterruptedException
49*3e359d9cSTom Erickson     {
50*3e359d9cSTom Erickson 	Aggregate aggregate;
51*3e359d9cSTom Erickson 	Set <String> included = new HashSet <String> ();
52*3e359d9cSTom Erickson 	int n = 1;
53*3e359d9cSTom Erickson 
54*3e359d9cSTom Erickson 	for (String name : aggregationNames) {
55*3e359d9cSTom Erickson 	    included.add(name);
56*3e359d9cSTom Erickson 	}
57*3e359d9cSTom Erickson 
58*3e359d9cSTom Erickson 	// Wait up to a full second to obtain aggregate data. Without a
59*3e359d9cSTom Erickson 	// time limit, we'll loop forever if no aggregation was
60*3e359d9cSTom Erickson 	// successfully included.
61*3e359d9cSTom Erickson 	do {
62*3e359d9cSTom Erickson 	    Thread.sleep(TICK);
63*3e359d9cSTom Erickson 	    aggregate = consumer.getAggregate(included, null);
64*3e359d9cSTom Erickson 	} while (aggregate.asMap().isEmpty() && n++ < (1000 / TICK));
65*3e359d9cSTom Erickson 
66*3e359d9cSTom Erickson 	for (String name : included) {
67*3e359d9cSTom Erickson 	    if (aggregate.getAggregation(name) == null) {
68*3e359d9cSTom Erickson 		throw new IllegalStateException("@" + name +
69*3e359d9cSTom Erickson 			" was explicitly included but did not appear " +
70*3e359d9cSTom Erickson 			"in the aggregate");
71*3e359d9cSTom Erickson 	    }
72*3e359d9cSTom Erickson 	}
73*3e359d9cSTom Erickson 	for (Aggregation a : aggregate.getAggregations()) {
74*3e359d9cSTom Erickson 	    if (!included.contains(a.getName())) {
75*3e359d9cSTom Erickson 		throw new IllegalStateException("@" + a.getName() +
76*3e359d9cSTom Erickson 			" was not explicitly included but appeared " +
77*3e359d9cSTom Erickson 			"in the aggregate anyway");
78*3e359d9cSTom Erickson 	    }
79*3e359d9cSTom Erickson 	}
80*3e359d9cSTom Erickson 
81*3e359d9cSTom Erickson 	if (!consumer.isRunning()) {
82*3e359d9cSTom Erickson 	    throw new IllegalStateException("consumer exited");
83*3e359d9cSTom Erickson 	}
84*3e359d9cSTom Erickson     }
85*3e359d9cSTom Erickson 
86*3e359d9cSTom Erickson     static void
testCleared(Consumer consumer, String ... aggregationNames)87*3e359d9cSTom Erickson     testCleared(Consumer consumer, String ... aggregationNames)
88*3e359d9cSTom Erickson 	    throws DTraceException, InterruptedException
89*3e359d9cSTom Erickson     {
90*3e359d9cSTom Erickson 	Aggregate aggregate;
91*3e359d9cSTom Erickson 	AggregationRecord rec;
92*3e359d9cSTom Erickson 	long value;
93*3e359d9cSTom Erickson 	Long firstValue;
94*3e359d9cSTom Erickson 	int n = 1;
95*3e359d9cSTom Erickson 	Map <String, Long> firstValues = new HashMap <String, Long> ();
96*3e359d9cSTom Erickson 	Set <String> cleared = new HashSet <String> ();
97*3e359d9cSTom Erickson 
98*3e359d9cSTom Erickson 	for (String name : aggregationNames) {
99*3e359d9cSTom Erickson 	    cleared.add(name);
100*3e359d9cSTom Erickson 	}
101*3e359d9cSTom Erickson 
102*3e359d9cSTom Erickson 	do {
103*3e359d9cSTom Erickson 	    Thread.sleep(TICK);
104*3e359d9cSTom Erickson 	    aggregate = consumer.getAggregate(null, cleared);
105*3e359d9cSTom Erickson 	} while (aggregate.asMap().isEmpty() && n++ < (1000 / TICK));
106*3e359d9cSTom Erickson 	n = 1;
107*3e359d9cSTom Erickson 
108*3e359d9cSTom Erickson 	do {
109*3e359d9cSTom Erickson 	    Thread.sleep(TICK * EXPECTED_TICKS);
110*3e359d9cSTom Erickson 	    aggregate = consumer.getAggregate(null, cleared);
111*3e359d9cSTom Erickson 
112*3e359d9cSTom Erickson 	    for (Aggregation a : aggregate.getAggregations()) {
113*3e359d9cSTom Erickson 		if (!firstValues.containsKey(a.getName())) {
114*3e359d9cSTom Erickson 		    rec = a.getRecord(Tuple.EMPTY);
115*3e359d9cSTom Erickson 		    value = rec.getValue().getValue().longValue();
116*3e359d9cSTom Erickson 		    firstValues.put(a.getName(), value);
117*3e359d9cSTom Erickson 		}
118*3e359d9cSTom Erickson 	    }
119*3e359d9cSTom Erickson 	} while (consumer.isRunning() && n++ < INTERVALS);
120*3e359d9cSTom Erickson 
121*3e359d9cSTom Erickson 	for (Aggregation a : aggregate.getAggregations()) {
122*3e359d9cSTom Erickson 	    rec = a.getRecord(Tuple.EMPTY);
123*3e359d9cSTom Erickson 	    value = rec.getValue().getValue().longValue();
124*3e359d9cSTom Erickson 	    firstValue = firstValues.get(a.getName());
125*3e359d9cSTom Erickson 
126*3e359d9cSTom Erickson 	    if (cleared.contains(a.getName())) {
127*3e359d9cSTom Erickson 		// last value should be about the same as first value
128*3e359d9cSTom Erickson 		if (value > (firstValue * 2)) {
129*3e359d9cSTom Erickson 		    throw new IllegalStateException(
130*3e359d9cSTom Erickson 			    "@" + a.getName() + " should have " +
131*3e359d9cSTom Erickson 			    "been cleared but instead grew from " +
132*3e359d9cSTom Erickson 			    firstValue + " to " + value);
133*3e359d9cSTom Erickson 		}
134*3e359d9cSTom Erickson 	    } else {
135*3e359d9cSTom Erickson 		// last value should be about (INTERVALS * firstValue)
136*3e359d9cSTom Erickson 		if (value < (firstValue * 2)) {
137*3e359d9cSTom Erickson 		    throw new IllegalStateException(
138*3e359d9cSTom Erickson 			    "@" + a.getName() + " should have " +
139*3e359d9cSTom Erickson 			    "accumulated a running total but " +
140*3e359d9cSTom Erickson 			    "instead went from " +
141*3e359d9cSTom Erickson 			    firstValue + " to " + value);
142*3e359d9cSTom Erickson 		}
143*3e359d9cSTom Erickson 	    }
144*3e359d9cSTom Erickson 	}
145*3e359d9cSTom Erickson 
146*3e359d9cSTom Erickson 	if (!consumer.isRunning()) {
147*3e359d9cSTom Erickson 	    throw new IllegalStateException("consumer exited");
148*3e359d9cSTom Erickson 	}
149*3e359d9cSTom Erickson     }
150*3e359d9cSTom Erickson 
151*3e359d9cSTom Erickson     static Integer includedStatus;
152*3e359d9cSTom Erickson     static Integer clearedStatus;
153*3e359d9cSTom Erickson 
154*3e359d9cSTom Erickson     static void
startIncludedTest()155*3e359d9cSTom Erickson     startIncludedTest()
156*3e359d9cSTom Erickson     {
157*3e359d9cSTom Erickson 	final Consumer consumer = new LocalConsumer();
158*3e359d9cSTom Erickson 	consumer.addConsumerListener(new ConsumerAdapter() {
159*3e359d9cSTom Erickson 	    public void consumerStarted(ConsumerEvent e) {
160*3e359d9cSTom Erickson 		new Thread(new Runnable() {
161*3e359d9cSTom Erickson 		    public void run() {
162*3e359d9cSTom Erickson 			try {
163*3e359d9cSTom Erickson 			    testIncluded(consumer, ANONYMOUS_AGGREGATION);
164*3e359d9cSTom Erickson 			    includedStatus = 0;
165*3e359d9cSTom Erickson 			} catch (Exception e) {
166*3e359d9cSTom Erickson 			    includedStatus = 1;
167*3e359d9cSTom Erickson 			    e.printStackTrace();
168*3e359d9cSTom Erickson 			} finally {
169*3e359d9cSTom Erickson 			    consumer.abort();
170*3e359d9cSTom Erickson 			}
171*3e359d9cSTom Erickson 		    }
172*3e359d9cSTom Erickson 		}).start();
173*3e359d9cSTom Erickson 	    }
174*3e359d9cSTom Erickson 	});
175*3e359d9cSTom Erickson 
176*3e359d9cSTom Erickson 	try {
177*3e359d9cSTom Erickson 	    consumer.open();
178*3e359d9cSTom Erickson 	    consumer.setOption(Option.aggrate, Option.millis(TICK));
179*3e359d9cSTom Erickson 	    consumer.compile(programString);
180*3e359d9cSTom Erickson 	    consumer.enable();
181*3e359d9cSTom Erickson 	    consumer.go();
182*3e359d9cSTom Erickson 	} catch (Exception e) {
183*3e359d9cSTom Erickson 	    includedStatus = 1;
184*3e359d9cSTom Erickson 	    e.printStackTrace();
185*3e359d9cSTom Erickson 	}
186*3e359d9cSTom Erickson     }
187*3e359d9cSTom Erickson 
188*3e359d9cSTom Erickson     static void
startClearedTest()189*3e359d9cSTom Erickson     startClearedTest()
190*3e359d9cSTom Erickson     {
191*3e359d9cSTom Erickson 	final Consumer consumer = new LocalConsumer();
192*3e359d9cSTom Erickson 	consumer.addConsumerListener(new ConsumerAdapter() {
193*3e359d9cSTom Erickson 	    public void consumerStarted(ConsumerEvent e) {
194*3e359d9cSTom Erickson 		new Thread(new Runnable() {
195*3e359d9cSTom Erickson 		    public void run() {
196*3e359d9cSTom Erickson 			try {
197*3e359d9cSTom Erickson 			    testCleared(consumer, ANONYMOUS_AGGREGATION);
198*3e359d9cSTom Erickson 			    clearedStatus = 0;
199*3e359d9cSTom Erickson 			} catch (Exception e) {
200*3e359d9cSTom Erickson 			    clearedStatus = 1;
201*3e359d9cSTom Erickson 			    e.printStackTrace();
202*3e359d9cSTom Erickson 			} finally {
203*3e359d9cSTom Erickson 			    consumer.abort();
204*3e359d9cSTom Erickson 			}
205*3e359d9cSTom Erickson 		    }
206*3e359d9cSTom Erickson 		}).start();
207*3e359d9cSTom Erickson 	    }
208*3e359d9cSTom Erickson 	});
209*3e359d9cSTom Erickson 
210*3e359d9cSTom Erickson 	try {
211*3e359d9cSTom Erickson 	    consumer.open();
212*3e359d9cSTom Erickson 	    consumer.setOption(Option.aggrate, Option.millis(TICK));
213*3e359d9cSTom Erickson 	    consumer.compile(programString);
214*3e359d9cSTom Erickson 	    consumer.enable();
215*3e359d9cSTom Erickson 	    consumer.go();
216*3e359d9cSTom Erickson 	} catch (Exception e) {
217*3e359d9cSTom Erickson 	    clearedStatus = 1;
218*3e359d9cSTom Erickson 	    e.printStackTrace();
219*3e359d9cSTom Erickson 	}
220*3e359d9cSTom Erickson     }
221*3e359d9cSTom Erickson 
222*3e359d9cSTom Erickson     public static void
main(String[] args)223*3e359d9cSTom Erickson     main(String[] args)
224*3e359d9cSTom Erickson     {
225*3e359d9cSTom Erickson 	startIncludedTest();
226*3e359d9cSTom Erickson 
227*3e359d9cSTom Erickson 	do {
228*3e359d9cSTom Erickson 	    try {
229*3e359d9cSTom Erickson 		Thread.sleep(TICK);
230*3e359d9cSTom Erickson 	    } catch (InterruptedException e) {
231*3e359d9cSTom Erickson 		e.printStackTrace();
232*3e359d9cSTom Erickson 	    }
233*3e359d9cSTom Erickson 	} while (includedStatus == null);
234*3e359d9cSTom Erickson 
235*3e359d9cSTom Erickson 	startClearedTest();
236*3e359d9cSTom Erickson 
237*3e359d9cSTom Erickson 	do {
238*3e359d9cSTom Erickson 	    try {
239*3e359d9cSTom Erickson 		Thread.sleep(TICK);
240*3e359d9cSTom Erickson 	    } catch (InterruptedException e) {
241*3e359d9cSTom Erickson 		e.printStackTrace();
242*3e359d9cSTom Erickson 	    }
243*3e359d9cSTom Erickson 	} while (clearedStatus == null);
244*3e359d9cSTom Erickson 
245*3e359d9cSTom Erickson 	if (includedStatus != 0 || clearedStatus != 0) {
246*3e359d9cSTom Erickson 	    System.out.println("Failure");
247*3e359d9cSTom Erickson 	    System.exit(1);
248*3e359d9cSTom Erickson 	}
249*3e359d9cSTom Erickson 
250*3e359d9cSTom Erickson 	System.out.println("Success");
251*3e359d9cSTom Erickson     }
252*3e359d9cSTom Erickson }
253