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