c2b18f6d0c4ded723a6f0a7ee0622edf1fc748d1
[utils] / support / general / src / test / java / org / wamblee / test / EventTracker.java
1 /*
2  * Copyright 2005-2010 the original author or authors.
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */ 
16 package org.wamblee.test;
17
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.logging.Logger;
24
25 /**
26  * Tracks the occurence of certain events in a test environment. Threads in a
27  * test environment tell the event tracker of the occurrence of certain events
28  * using {@link #eventOccurred(Event)}. Test code inspects the events sent by a
29  * thread using {@link #isEventSent(Thread, Event)}.
30  * 
31  * A record is kept of every event which is sent. Therefore, the occurrence of a
32  * new event does not erase a previously sent event.
33  * 
34  * @param <Event>
35  *            Type of event sent from test code. Usually String will be
36  *            sufficient. The event type must provide a sensible implementation
37  *            of {@link java.lang.Object#equals(java.lang.Object)}.
38  * 
39  * @author Erik Brakkee
40  */
41 public class EventTracker<Event> {
42     private static final Logger LOG = Logger.getLogger(EventTracker.class.getName());
43
44     /**
45      * Map of Thread object to a list of events.
46      */
47     private Map<Thread, List<Event>> events;
48
49     /**
50      * Constructs the event tracker.
51      * 
52      */
53     public EventTracker() {
54         clear();
55     }
56
57     public synchronized void clear() {
58         events = new HashMap<Thread, List<Event>>();
59     }
60
61     /**
62      * Called by a thread to inform that an event has occurred.
63      * 
64      * @param aEvent
65      *            Event that was sent.
66      */
67     public synchronized void eventOccurred(Event aEvent) {
68         LOG.info("Event '" + aEvent + "' sent.");
69
70         Thread current = Thread.currentThread();
71         List<Event> eventList = events.get(current);
72
73         if (eventList == null) {
74             eventList = new ArrayList<Event>();
75             events.put(current, eventList);
76         }
77
78         eventList.add(aEvent);
79     }
80
81     /**
82      * Checks if a specific event has happened in a specific thread.
83      * 
84      * @param aThread
85      *            Thread to check.
86      * @param aEvent
87      *            Event to check for.
88      * @return Whether or not the event was sent.
89      */
90     public synchronized boolean isEventSent(Thread aThread, Event aEvent) {
91         List<Event> eventList = events.get(aThread);
92
93         if (eventList == null) {
94             return false;
95         }
96
97         return eventList.contains(aEvent);
98     }
99
100     /**
101      * Gets the events for a thread in the order they were sent
102      * 
103      * @param aThread
104      *            Thread to get events for.
105      * @return Events that were sent. A zero-sized array is returned if no
106      *         events were sent.
107      */
108     public synchronized List<Event> getEvents(Thread aThread) {
109         List<Event> eventList = events.get(aThread);
110
111         if (eventList == null) {
112             eventList = Collections.emptyList();
113         }
114
115         return Collections.unmodifiableList(eventList);
116     }
117
118     /**
119      * Gets the number of times an event was sent summed up over all threads.
120      * 
121      * @param aEvent
122      *            Event to check.
123      * @return Number of times it was reached.
124      */
125     public synchronized int getEventCount(Event aEvent) {
126         int count = 0;
127
128         for (Thread thread : events.keySet()) {
129             List<Event> eventList = events.get(thread);
130
131             for (Event event : eventList) {
132                 if (event.equals(aEvent)) {
133                     count++;
134                 }
135             }
136         }
137
138         return count;
139     }
140
141     /**
142      * Gets the total event count over all threads.
143      * 
144      * @return
145      */
146     public synchronized int getEventCount() {
147         int count = 0;
148
149         for (Thread thread : events.keySet()) {
150             count += events.get(thread).size();
151         }
152
153         return count;
154     }
155 }