1210753Srpaulo/*
2210753Srpaulo * CDDL HEADER START
3210753Srpaulo *
4210753Srpaulo * The contents of this file are subject to the terms of the
5210753Srpaulo * Common Development and Distribution License (the "License").
6210753Srpaulo * You may not use this file except in compliance with the License.
7210753Srpaulo *
8210753Srpaulo * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9210753Srpaulo * or http://www.opensolaris.org/os/licensing.
10210753Srpaulo * See the License for the specific language governing permissions
11210753Srpaulo * and limitations under the License.
12210753Srpaulo *
13210753Srpaulo * When distributing Covered Code, include this CDDL HEADER in each
14210753Srpaulo * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15210753Srpaulo * If applicable, add the following below this CDDL HEADER, with the
16210753Srpaulo * fields enclosed by brackets "[]" replaced with your own identifying
17210753Srpaulo * information: Portions Copyright [yyyy] [name of copyright owner]
18210753Srpaulo *
19210753Srpaulo * CDDL HEADER END
20210753Srpaulo */
21210753Srpaulo
22210753Srpaulo/*
23210753Srpaulo * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24210753Srpaulo * Use is subject to license terms.
25210753Srpaulo */
26210753Srpaulo
27210753Srpauloimport org.opensolaris.os.dtrace.*;
28210753Srpauloimport java.util.*;
29210753Srpaulo
30210753Srpaulo/**
31210753Srpaulo * Assert getAggregate() can explicitly specify the anonymous aggregation.
32210753Srpaulo */
33210753Srpaulopublic class TestGetAggregate {
34210753Srpaulo    static final String programString =
35210753Srpaulo	    "profile:::tick-50ms" +
36210753Srpaulo	    "{" +
37210753Srpaulo	    "        @ = count();" +
38210753Srpaulo	    "        @a = count();" +
39210753Srpaulo	    "}";
40210753Srpaulo
41210753Srpaulo    static final String ANONYMOUS_AGGREGATION = "";
42210753Srpaulo    static final int TICK = 50;
43210753Srpaulo    static final int EXPECTED_TICKS = 3;
44210753Srpaulo    static final int INTERVALS = 4;
45210753Srpaulo
46210753Srpaulo    static void
47210753Srpaulo    testIncluded(Consumer consumer, String ... aggregationNames)
48210753Srpaulo	    throws DTraceException, InterruptedException
49210753Srpaulo    {
50210753Srpaulo	Aggregate aggregate;
51210753Srpaulo	Set <String> included = new HashSet <String> ();
52210753Srpaulo	int n = 1;
53210753Srpaulo
54210753Srpaulo	for (String name : aggregationNames) {
55210753Srpaulo	    included.add(name);
56210753Srpaulo	}
57210753Srpaulo
58210753Srpaulo	// Wait up to a full second to obtain aggregate data. Without a
59210753Srpaulo	// time limit, we'll loop forever if no aggregation was
60210753Srpaulo	// successfully included.
61210753Srpaulo	do {
62210753Srpaulo	    Thread.sleep(TICK);
63210753Srpaulo	    aggregate = consumer.getAggregate(included, null);
64210753Srpaulo	} while (aggregate.asMap().isEmpty() && n++ < (1000 / TICK));
65210753Srpaulo
66210753Srpaulo	for (String name : included) {
67210753Srpaulo	    if (aggregate.getAggregation(name) == null) {
68210753Srpaulo		throw new IllegalStateException("@" + name +
69210753Srpaulo			" was explicitly included but did not appear " +
70210753Srpaulo			"in the aggregate");
71210753Srpaulo	    }
72210753Srpaulo	}
73210753Srpaulo	for (Aggregation a : aggregate.getAggregations()) {
74210753Srpaulo	    if (!included.contains(a.getName())) {
75210753Srpaulo		throw new IllegalStateException("@" + a.getName() +
76210753Srpaulo			" was not explicitly included but appeared " +
77210753Srpaulo			"in the aggregate anyway");
78210753Srpaulo	    }
79210753Srpaulo	}
80210753Srpaulo
81210753Srpaulo	if (!consumer.isRunning()) {
82210753Srpaulo	    throw new IllegalStateException("consumer exited");
83210753Srpaulo	}
84210753Srpaulo    }
85210753Srpaulo
86210753Srpaulo    static void
87210753Srpaulo    testCleared(Consumer consumer, String ... aggregationNames)
88210753Srpaulo	    throws DTraceException, InterruptedException
89210753Srpaulo    {
90210753Srpaulo	Aggregate aggregate;
91210753Srpaulo	AggregationRecord rec;
92210753Srpaulo	long value;
93210753Srpaulo	Long firstValue;
94210753Srpaulo	int n = 1;
95210753Srpaulo	Map <String, Long> firstValues = new HashMap <String, Long> ();
96210753Srpaulo	Set <String> cleared = new HashSet <String> ();
97210753Srpaulo
98210753Srpaulo	for (String name : aggregationNames) {
99210753Srpaulo	    cleared.add(name);
100210753Srpaulo	}
101210753Srpaulo
102210753Srpaulo	do {
103210753Srpaulo	    Thread.sleep(TICK);
104210753Srpaulo	    aggregate = consumer.getAggregate(null, cleared);
105210753Srpaulo	} while (aggregate.asMap().isEmpty() && n++ < (1000 / TICK));
106210753Srpaulo	n = 1;
107210753Srpaulo
108210753Srpaulo	do {
109210753Srpaulo	    Thread.sleep(TICK * EXPECTED_TICKS);
110210753Srpaulo	    aggregate = consumer.getAggregate(null, cleared);
111210753Srpaulo
112210753Srpaulo	    for (Aggregation a : aggregate.getAggregations()) {
113210753Srpaulo		if (!firstValues.containsKey(a.getName())) {
114210753Srpaulo		    rec = a.getRecord(Tuple.EMPTY);
115210753Srpaulo		    value = rec.getValue().getValue().longValue();
116210753Srpaulo		    firstValues.put(a.getName(), value);
117210753Srpaulo		}
118210753Srpaulo	    }
119210753Srpaulo	} while (consumer.isRunning() && n++ < INTERVALS);
120210753Srpaulo
121210753Srpaulo	for (Aggregation a : aggregate.getAggregations()) {
122210753Srpaulo	    rec = a.getRecord(Tuple.EMPTY);
123210753Srpaulo	    value = rec.getValue().getValue().longValue();
124210753Srpaulo	    firstValue = firstValues.get(a.getName());
125210753Srpaulo
126210753Srpaulo	    if (cleared.contains(a.getName())) {
127210753Srpaulo		// last value should be about the same as first value
128210753Srpaulo		if (value > (firstValue * 2)) {
129210753Srpaulo		    throw new IllegalStateException(
130210753Srpaulo			    "@" + a.getName() + " should have " +
131210753Srpaulo			    "been cleared but instead grew from " +
132210753Srpaulo			    firstValue + " to " + value);
133210753Srpaulo		}
134210753Srpaulo	    } else {
135210753Srpaulo		// last value should be about (INTERVALS * firstValue)
136210753Srpaulo		if (value < (firstValue * 2)) {
137210753Srpaulo		    throw new IllegalStateException(
138210753Srpaulo			    "@" + a.getName() + " should have " +
139210753Srpaulo			    "accumulated a running total but " +
140210753Srpaulo			    "instead went from " +
141210753Srpaulo			    firstValue + " to " + value);
142210753Srpaulo		}
143210753Srpaulo	    }
144210753Srpaulo	}
145210753Srpaulo
146210753Srpaulo	if (!consumer.isRunning()) {
147210753Srpaulo	    throw new IllegalStateException("consumer exited");
148210753Srpaulo	}
149210753Srpaulo    }
150210753Srpaulo
151210753Srpaulo    static Integer includedStatus;
152210753Srpaulo    static Integer clearedStatus;
153210753Srpaulo
154210753Srpaulo    static void
155210753Srpaulo    startIncludedTest()
156210753Srpaulo    {
157210753Srpaulo	final Consumer consumer = new LocalConsumer();
158210753Srpaulo	consumer.addConsumerListener(new ConsumerAdapter() {
159210753Srpaulo	    public void consumerStarted(ConsumerEvent e) {
160210753Srpaulo		new Thread(new Runnable() {
161210753Srpaulo		    public void run() {
162210753Srpaulo			try {
163210753Srpaulo			    testIncluded(consumer, ANONYMOUS_AGGREGATION);
164210753Srpaulo			    includedStatus = 0;
165210753Srpaulo			} catch (Exception e) {
166210753Srpaulo			    includedStatus = 1;
167210753Srpaulo			    e.printStackTrace();
168210753Srpaulo			} finally {
169210753Srpaulo			    consumer.abort();
170210753Srpaulo			}
171210753Srpaulo		    }
172210753Srpaulo		}).start();
173210753Srpaulo	    }
174210753Srpaulo	});
175210753Srpaulo
176210753Srpaulo	try {
177210753Srpaulo	    consumer.open();
178210753Srpaulo	    consumer.setOption(Option.aggrate, Option.millis(TICK));
179210753Srpaulo	    consumer.compile(programString);
180210753Srpaulo	    consumer.enable();
181210753Srpaulo	    consumer.go();
182210753Srpaulo	} catch (Exception e) {
183210753Srpaulo	    includedStatus = 1;
184210753Srpaulo	    e.printStackTrace();
185210753Srpaulo	}
186210753Srpaulo    }
187210753Srpaulo
188210753Srpaulo    static void
189210753Srpaulo    startClearedTest()
190210753Srpaulo    {
191210753Srpaulo	final Consumer consumer = new LocalConsumer();
192210753Srpaulo	consumer.addConsumerListener(new ConsumerAdapter() {
193210753Srpaulo	    public void consumerStarted(ConsumerEvent e) {
194210753Srpaulo		new Thread(new Runnable() {
195210753Srpaulo		    public void run() {
196210753Srpaulo			try {
197210753Srpaulo			    testCleared(consumer, ANONYMOUS_AGGREGATION);
198210753Srpaulo			    clearedStatus = 0;
199210753Srpaulo			} catch (Exception e) {
200210753Srpaulo			    clearedStatus = 1;
201210753Srpaulo			    e.printStackTrace();
202210753Srpaulo			} finally {
203210753Srpaulo			    consumer.abort();
204210753Srpaulo			}
205210753Srpaulo		    }
206210753Srpaulo		}).start();
207210753Srpaulo	    }
208210753Srpaulo	});
209210753Srpaulo
210210753Srpaulo	try {
211210753Srpaulo	    consumer.open();
212210753Srpaulo	    consumer.setOption(Option.aggrate, Option.millis(TICK));
213210753Srpaulo	    consumer.compile(programString);
214210753Srpaulo	    consumer.enable();
215210753Srpaulo	    consumer.go();
216210753Srpaulo	} catch (Exception e) {
217210753Srpaulo	    clearedStatus = 1;
218210753Srpaulo	    e.printStackTrace();
219210753Srpaulo	}
220210753Srpaulo    }
221210753Srpaulo
222210753Srpaulo    public static void
223210753Srpaulo    main(String[] args)
224210753Srpaulo    {
225210753Srpaulo	startIncludedTest();
226210753Srpaulo
227210753Srpaulo	do {
228210753Srpaulo	    try {
229210753Srpaulo		Thread.sleep(TICK);
230210753Srpaulo	    } catch (InterruptedException e) {
231210753Srpaulo		e.printStackTrace();
232210753Srpaulo	    }
233210753Srpaulo	} while (includedStatus == null);
234210753Srpaulo
235210753Srpaulo	startClearedTest();
236210753Srpaulo
237210753Srpaulo	do {
238210753Srpaulo	    try {
239210753Srpaulo		Thread.sleep(TICK);
240210753Srpaulo	    } catch (InterruptedException e) {
241210753Srpaulo		e.printStackTrace();
242210753Srpaulo	    }
243210753Srpaulo	} while (clearedStatus == null);
244210753Srpaulo
245210753Srpaulo	if (includedStatus != 0 || clearedStatus != 0) {
246210753Srpaulo	    System.out.println("Failure");
247210753Srpaulo	    System.exit(1);
248210753Srpaulo	}
249210753Srpaulo
250210753Srpaulo	System.out.println("Success");
251210753Srpaulo    }
252210753Srpaulo}
253