Source code: com/xpn/xwiki/test/MonitorTest.java
1 /**
2 * ===================================================================
3 *
4 * Copyright (c) 2003-2005 Ludovic Dubost, All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details, published at
15 * http://www.gnu.org/copyleft/lesser.html or in lesser.txt in the
16 * root folder of this distribution.
17 */
18 package com.xpn.xwiki.test;
19
20 import com.xpn.xwiki.XWiki;
21 import com.xpn.xwiki.XWikiContext;
22 import com.xpn.xwiki.monitor.api.MonitorData;
23 import com.xpn.xwiki.monitor.api.MonitorTimer;
24 import com.xpn.xwiki.monitor.api.MonitorPlugin;
25 import com.xpn.xwiki.web.XWikiServletURLFactory;
26 import java.net.URL;
27 import java.net.MalformedURLException;
28 import java.util.Date;
29 import java.util.Map;
30
31 import org.apache.commons.collections.buffer.CircularFifoBuffer;
32
33 public class MonitorTest extends HibernateTestCase {
34
35 private String surl = "http://127.0.0.1:9080/xwiki/bin/view/Main/WebHome";
36 private String page = "xwiki:Main.WebHome1";
37 private String action = "view";
38
39 private XWikiContext context2;
40 private String surl2 = "http://127.0.0.1:9080/xwiki/bin/view/Main/WebHome2";
41 private String page2 = "xwiki:Main.WebHome2";
42 private String action2 = "view";
43
44
45 public void setUp() throws Exception {
46 super.setUp();
47 getXWiki().getPluginManager().addPlugin("monitor","com.xpn.xwiki.monitor.api.MonitorPlugin", getXWikiContext());
48 getXWikiContext().setURLFactory(new XWikiServletURLFactory(new URL("http://www.xwiki.org/"), "xwiki/" , "bin/"));
49
50 context2 = new XWikiContext();
51 context2.setWiki(getXWiki());
52 context2.setURLFactory(new XWikiServletURLFactory(new URL("http://www.xwiki.org/"), "xwiki/" , "bin/"));
53 }
54
55 public void testMonitorData() throws MalformedURLException {
56 MonitorData monitordata = new MonitorData( page, action, new URL(surl), "");
57 assertEquals("Monitor URL is incorrect", surl, monitordata.getURL().toString());
58 assertEquals("Monitor Wiki page is incorrect", page, monitordata.getWikiPage());
59 Date time1 = new Date();
60 monitordata.startRequest(page, new URL(surl));
61 try {
62 Thread.sleep(4000);
63 } catch (InterruptedException e) {
64 }
65 monitordata.endRequest();
66 Date time2 = new Date();
67 assertTrue("Time is smaller than sleep duraction: " + monitordata.getDuration(), (monitordata.getDuration()>=3000));
68 assertTrue("Surrounding time is smaller than request time: " + monitordata.getDuration() + " " + (time2.getTime()-time1.getTime()), (time2.getTime()-time1.getTime())>=monitordata.getDuration());
69 assertTrue("Surrounding time is smaller than sql time: " + (time2.getTime()-time1.getTime()) + " " + monitordata.getDuration("sql"), (time2.getTime()-time1.getTime())>=monitordata.getDuration("sql"));
70 }
71
72 public void testMonitorDataWithTimerDetails() throws MalformedURLException {
73 MonitorData monitordata = new MonitorData( page, action, new URL(surl), "");
74 assertEquals("Monitor URL is incorrect", surl, monitordata.getURL().toString());
75 assertEquals("Monitor Wiki page is incorrect", page, monitordata.getWikiPage());
76 Date time1 = new Date();
77 monitordata.startRequest(page, new URL(surl));
78 try { Thread.sleep(510);} catch (InterruptedException e) {}
79 monitordata.startTimer("sql", "select count(*) from toto");
80 try { Thread.sleep(1600);} catch (InterruptedException e) {}
81 monitordata.endTimer("sql");
82 try { Thread.sleep(510);} catch (InterruptedException e) {}
83 monitordata.endRequest();
84 Date time2 = new Date();
85 assertTrue("Time is smaller than sleep duraction", (monitordata.getDuration()>=2000));
86 assertTrue("SQL Time is smaller than sleep duraction", (monitordata.getDuration("sql")>=1000));
87 assertTrue("Surrounding time is smaller than request time", (time2.getTime()-time1.getTime())>=monitordata.getDuration());
88 assertTrue("Surrounding time is smaller than sql time", (time2.getTime()-time1.getTime())>=monitordata.getDuration("sql"));
89 assertEquals("Timer list is of incorrect size", monitordata.getTimerList().size(), 1);
90 MonitorTimer timer = (MonitorTimer) monitordata.getTimerList().get(0);
91 assertEquals("Timer details are incorrect", timer.getDetails(), "select count(*) from toto");
92 assertTrue("Timer time is incorrect", (timer.getDuration()>=1000));
93 }
94
95 public void testMonitorDataWithoutTimerDetails() throws MalformedURLException {
96 MonitorData monitordata = new MonitorData( page, action, new URL(surl), "");
97 monitordata.setURL(new URL(surl));
98 assertEquals("Monitor URL is incorrect", surl, monitordata.getURL().toString());
99 monitordata.setWikiPage(page);
100 assertEquals("Monitor Wiki page is incorrect", page, monitordata.getWikiPage());
101 Date time1 = new Date();
102 monitordata.startRequest(page, new URL(surl));
103 try { Thread.sleep(110);} catch (InterruptedException e) {}
104 monitordata.startTimer("sql");
105 try { Thread.sleep(1100);} catch (InterruptedException e) {}
106 monitordata.endTimer("sql");
107 try { Thread.sleep(100);} catch (InterruptedException e) {}
108 monitordata.endRequest();
109 Date time2 = new Date();
110 assertTrue("Time is smaller than sleep duraction: " + monitordata.getDuration(), (monitordata.getDuration()>=1200));
111 assertTrue("SQL Time is smaller than sleep duraction: " + monitordata.getDuration("sql"), (monitordata.getDuration("sql")>=1000));
112 assertTrue("Surrounding time is smaller than request time", (time2.getTime()-time1.getTime())>=monitordata.getDuration());
113 assertTrue("Surrounding time is smaller than sql time", (time2.getTime()-time1.getTime())>=monitordata.getDuration("sql"));
114 assertEquals("Timer list should be zero because we have no details", monitordata.getTimerList().size(), 0);
115 }
116
117 public void testGetPlugin() {
118 MonitorPlugin monitor = (MonitorPlugin) getXWiki().getPlugin("monitor", getXWikiContext());
119 assertNotNull("Monitor Plugin is null", monitor);
120 }
121
122 public void testGetMonitorData() throws MalformedURLException {
123 MonitorPlugin monitor = (MonitorPlugin) getXWiki().getPlugin("monitor", getXWikiContext());
124 assertNotNull("Monitor Plugin is null", monitor);
125 long duration = 1100;
126 // Test
127 monitor.startRequest(page, action, new URL(surl));
128 try { Thread.sleep(duration);} catch (InterruptedException e) {}
129 monitor.startTimer("sql");
130 try { Thread.sleep(duration);} catch (InterruptedException e) {}
131 monitor.endTimer("sql");
132 try { Thread.sleep(duration);} catch (InterruptedException e) {}
133 monitor.startTimer("sql");
134 try { Thread.sleep(duration);} catch (InterruptedException e) {}
135 monitor.endTimer("sql");
136 try { Thread.sleep(duration);} catch (InterruptedException e) {}
137
138 // Verify it is empty
139 CircularFifoBuffer list = monitor.getLastTimerData();
140 assertEquals("Timer Data list is incorrect", 0, list.size());
141
142 monitor.endRequest();
143
144 list = monitor.getLastTimerData();
145 assertEquals("Timer Data list is incorrect", 1, list.size());
146 MonitorData mdata1 = (MonitorData) list.toArray()[0];
147 // List is inverted.. last one first.. it should be the first request that was longer
148 assertEquals("Timer Data list is incorrect", "xwiki:Main.WebHome1", mdata1.getWikiPage());
149 assertTrue("Timer Data 1 is incorrect: " + mdata1.getDuration(), mdata1.getDuration()>=1500);
150 assertTrue("Timer Total is incorrect: " + monitor.getDuration(), monitor.getDuration()>=2000);
151 }
152
153 public void testGetMonitorDataWithThread(MonitorPlugin monitor, int test, long duration1, long duration2) throws MalformedURLException {
154 assertNotNull("Monitor Plugin is null", monitor);
155 MonitorTestThread monitorthread1 = new MonitorTestThread(getXWiki(), getXWikiContext(), page, action, new URL(surl), duration1, test);
156 Thread t1 = new Thread(monitorthread1);
157 MonitorTestThread monitorthread2 = new MonitorTestThread(getXWiki(), context2, page2, action, new URL(surl2), duration2, test);
158 Thread t2 = new Thread(monitorthread2);
159 t1.start();
160 t2.start();
161
162 while (t2.isAlive()) {
163 try {
164 t2.join();
165 } catch (InterruptedException e) {
166 }
167 }
168 // Verify it is empty
169 Map map = monitor.getActiveTimerData();
170 assertEquals("Active Timer Data Map is incorrect", 1, map.size());
171 CircularFifoBuffer list = monitor.getLastTimerData();
172 assertEquals("Intermediary Timer Data list is incorrect", 1, list.size());
173
174 while (t1.isAlive()) {
175 try {
176 t1.join();
177 } catch (InterruptedException e) {
178 }
179 }
180 }
181
182 public void testGetMonitorDataWithThread1() throws MalformedURLException {
183 MonitorPlugin monitor = (MonitorPlugin) getXWiki().getPlugin("monitor", getXWikiContext());
184 testGetMonitorDataWithThread(monitor, 1, 1100, 110);
185 CircularFifoBuffer list = monitor.getLastTimerData();
186 assertEquals("Timer Data list is incorrect", 2, list.size());
187 MonitorData mdata1 = (MonitorData) list.toArray()[1];
188 MonitorData mdata2 = (MonitorData) list.toArray()[0];
189 // List is inverted.. last one first.. it should be the first request that was longer
190 assertEquals("Timer Data list is incorrect", "xwiki:Main.WebHome1", mdata1.getWikiPage());
191 assertEquals("Timer Data list is incorrect", "xwiki:Main.WebHome2", mdata2.getWikiPage());
192 assertTrue("Timer Data 1 is incorrect: " + mdata1.getDuration(), mdata1.getDuration()>=1000);
193 assertTrue("Timer Data 2 is incorrect: " + mdata2.getDuration(), mdata2.getDuration()>=100);
194 assertTrue("Timer Total is incorrect: " + monitor.getDuration(), monitor.getDuration()>=1100);
195 }
196
197 public void testGetMonitorDataWithThread2() throws MalformedURLException {
198 MonitorPlugin monitor = (MonitorPlugin) getXWiki().getPlugin("monitor", getXWikiContext());
199 testGetMonitorDataWithThread(monitor, 2, 1100, 110);
200 CircularFifoBuffer list = monitor.getLastTimerData();
201 assertEquals("Timer Data list is incorrect", 2, list.size());
202 MonitorData mdata1 = (MonitorData) list.toArray()[1];
203 MonitorData mdata2 = (MonitorData) list.toArray()[0];
204 // List is inverted.. last one first.. it should be the first request that was longer
205 assertEquals("Timer Data list is incorrect", "xwiki:Main.WebHome1", mdata1.getWikiPage());
206 assertEquals("Timer Data list is incorrect", "xwiki:Main.WebHome2", mdata2.getWikiPage());
207 assertTrue("Timer Data 1 is incorrect: " + mdata1.getDuration(), mdata1.getDuration()>=5000);
208 assertTrue("Timer Data 2 is incorrect: " + mdata2.getDuration(), mdata2.getDuration()>=500);
209 assertTrue("Timer Total is incorrect: " + monitor.getDuration(), monitor.getDuration()>=5500);
210 assertTrue("Timer Data 1 is incorrect: " + mdata1.getDuration("sql"), mdata1.getDuration("sql")>=2000);
211 assertTrue("Timer Data 2 is incorrect: " + mdata2.getDuration("sql"), mdata2.getDuration("sql")>=200);
212 assertEquals("Timer Data 1 is incorrect", 2, mdata1.getNbCalls("sql"));
213 assertEquals("Timer Data 2 is incorrect", 2, mdata2.getNbCalls("sql"));
214 assertTrue("Timer Total is incorrect: " + monitor.getDuration("sql"), monitor.getDuration("sql")>=2200);
215 assertTrue("Timer Total is incorrect: " + monitor.getDuration(), monitor.getDuration()>=5500);
216 assertEquals("Timer Total is incorrect", 4, monitor.getNbCalls("sql"));
217 assertEquals("Timer Total is incorrect", 2, monitor.getRequests("sql"));
218 assertEquals("Timer Total is incorrect", 2, monitor.getRequests());
219 }
220
221 public class MonitorTestThread implements Runnable {
222 private XWiki xwiki;
223 private XWikiContext context;
224 private String page;
225 private String action;
226 private URL url;
227 private long duration;
228 private int test = 0;
229
230 public MonitorTestThread(XWiki xwiki, XWikiContext context, String page, String action, URL url, long duration, int test) {
231 this.xwiki = xwiki;
232 this.context = context;
233 this.url = url;
234 this.page = page;
235 this.duration = duration;
236 this.test = test;
237 this.action = action;
238 }
239
240 public void run1(MonitorPlugin monitor) {
241 try {
242 Thread.sleep(duration);
243 } catch (InterruptedException e) {
244 }
245 }
246
247 public void run2(MonitorPlugin monitor) {
248 try { Thread.sleep(duration);} catch (InterruptedException e) {}
249 monitor.startTimer("sql");
250 try { Thread.sleep(duration);} catch (InterruptedException e) {}
251 monitor.endTimer("sql");
252 try { Thread.sleep(duration);} catch (InterruptedException e) {}
253 monitor.startTimer("sql");
254 try { Thread.sleep(duration);} catch (InterruptedException e) {}
255 monitor.endTimer("sql");
256 try { Thread.sleep(duration);} catch (InterruptedException e) {}
257 }
258
259 public void run() {
260 context.setWiki(xwiki);
261 MonitorPlugin monitor = (MonitorPlugin) xwiki.getPlugin("monitor", context);
262 monitor.startRequest(page, action, url);
263 switch (test) {
264 case 1:
265 run1(monitor);
266 break;
267 case 2:
268 run2(monitor);
269 break;
270 }
271 monitor.endRequest();
272 }
273 }
274
275
276
277 }