View Javadoc

1   /*
2    * Copyright (c) 1998-2002 The Jgroup Team.
3    *
4    * This program is free software; you can redistribute it and/or modify
5    * it under the terms of the GNU Lesser General Public License version 2 as
6    * published by the Free Software Foundation.
7    *
8    * This program is distributed in the hope that it will be useful,
9    * but WITHOUT ANY WARRANTY; without even the implied warranty of
10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   * GNU Lesser General Public License for more details.
12   *
13   * You should have received a copy of the GNU Lesser General Public License
14   * along with this program; if not, write to the Free Software
15   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16   *
17   */
18  
19  package jgroup.test.performance.upgrade;
20  
21  import java.rmi.RemoteException;
22  
23  import jgroup.core.registry.DependableRegistry;
24  import jgroup.core.registry.RegistryFactory;
25  import jgroup.test.performance.SpeedTest;
26  
27  import org.apache.log4j.Logger;
28  
29  
30  
31  /**
32   *  This class is used to generate client requests with a given rate. 
33   *  The traffic is generated by repeated invocations sent to a given
34   *  test server. Basic statistics is computed based on the response time 
35   *  measurements taken during the process generation, including average,
36   *  min and max times. 
37   *
38   *  @author Marcin Solarski
39   *  @since Jgroup 2.1
40   */
41  class UpgradeClientTest
42  {
43  
44    ////////////////////////////////////////////////////////////////////////////////////////////
45    // Constants
46    ////////////////////////////////////////////////////////////////////////////////////////////
47  
48    /** Max number of */
49    private static final int CALIBRATE_NUM_CALLS = 10;
50    private static final int BUFFER_SIZE = 1000;
51  
52    /** number of mili seconds in a second */ 
53    private static final long  TIME_UNIT = 1000;  
54  
55    private SpeedTest test;
56    private boolean calibrated = false;
57    private DependableRegistry reg  = null;
58    private float avRespTime = 0;
59    private int method = 0;
60  
61     /** Obtain logger for this class */
62    private static Logger log = Logger.getLogger(UpgradeClientTest.class);
63  
64    /**
65     * default constuctor for the test. It resolves the name of the
66     * given server.
67     * Do not use thie constuctor for parrallel tests from one VMID.
68     * JGroup does not properly handles invocation generation for
69     * tests created that way.
70     */
71  
72    public UpgradeClientTest(String name) throws Exception {
73       prepareTest(name);
74    }
75  
76  
77    /**
78     * constructor to be used for multi-threaded test clients
79     */
80    public UpgradeClientTest(SpeedTest t) {
81      test = t;
82    }
83  
84  
85  
86    private void prepareTest(String name) throws Exception {
87          reg = RegistryFactory.getRegistry();
88          test = (SpeedTest) reg.lookup(name);
89    }
90  
91    /**
92     * sends requests to the server with a given rate for the given time period. 
93     * @param reqPerSec request rate (per second)
94     * @param call_no  that requests will be sent to the server
95     * @return a 3-element array of long with average, minimum and maximum times
96     */
97    public float generate_traffic(int reqPerSec, int call_no)
98    {
99      float time=0;
100     if( ! calibrated ) return 0;
101     long pauseTime = (long)( TIME_UNIT - reqPerSec * avRespTime) / reqPerSec;
102     
103     if (log.isDebugEnabled()) {
104       log.debug("Planned experiment time " + call_no*reqPerSec );
105       log.debug("Numer of calls " + call_no );
106       log.debug("Pause time for the given user traffic throughput (" + reqPerSec +") is equals to " + pauseTime);
107     }
108 
109     if( pauseTime < 0)  pauseTime = 0;
110 
111      if(method == 1) {
112 	time = test_method1(call_no, pauseTime);
113     } else if(method == 2) {
114 	time = test_method2(call_no, pauseTime);
115     } else if(method == 3) {
116 	time = test_method3(call_no, pauseTime, BUFFER_SIZE);
117     } else {
118 	time = test_method4(call_no, pauseTime, BUFFER_SIZE);
119     }
120 
121     log.debug("Average response time " + time );
122     return time;
123   
124   }
125 
126   /**
127    * calibrates the tests. Before a traffic can be generated, the test 
128    * has to be calibratedi with respect to the given testing method.
129    * @param method is a test method (1-4)
130    */
131     public float calibrate(int method) {
132 	    return calibrate(method, CALIBRATE_NUM_CALLS);
133     }
134 
135     
136     public float calibrate(int method, int calibReqCallNo) {
137       this.method= method;
138       avRespTime = computeAverageResponseTime(method, calibReqCallNo);
139       calibrated = true;
140       log.info("Average response time during calibration = " + avRespTime);
141       return avRespTime;
142     }
143 
144    /**
145     * compute an average response time for a given test method.
146     * This time is computed by sending a number of test calls to the 
147     * server, measuring the total time it took to process these calls
148     * and dividing by the number of calls sent.
149     * @param method is a test metho (1-4)
150     */
151     protected float computeAverageResponseTime(int method, int calibReqCallNo){
152     float  time = 0;
153 
154     if (log.isDebugEnabled()) log.info("Computing average Response Time ....");
155 
156     if(method == 1) {
157 	time = calibrate_method1(calibReqCallNo);
158     } else if(method == 2) {
159 	time = calibrate_method2(calibReqCallNo);
160     } else if(method == 3) {
161 	time = calibrate_method3(calibReqCallNo, BUFFER_SIZE);
162     } else {
163 	time = calibrate_method4(calibReqCallNo, BUFFER_SIZE);
164     }
165 
166     if (log.isDebugEnabled()) log.info("Average Response Time for method " + method + " equals to " + time);
167     return time;
168   }
169 
170 
171     private float calibrate_method1(int call_no) {
172       int j=0;
173       if( call_no<1 ) return 0;
174       try {
175 	long start = System.currentTimeMillis();
176         for (j=1; j <= call_no; j++) {
177           test.test();
178         }
179         return (System.currentTimeMillis() - start) / (float) call_no;
180       } catch(Exception e) {
181 	log.warn("Exception when calling method 2 no. " + j, e);
182         return 0;
183       }
184     }
185 
186     private float calibrate_method2(int call_no) {
187       int j=0;
188       if( call_no<1 ) return 0;
189       try {
190 	long start = System.currentTimeMillis();
191         for (j=1; j <= call_no; j++) {
192           test.mtest();
193         }
194         return (System.currentTimeMillis() - start) / (float) call_no;
195       } catch(Exception e) {
196 	log.warn("Exception when calling method 2 no. " + j, e);
197         return 0;
198       }
199     }
200 
201     
202      private float calibrate_method3(int call_no, int size) {
203       int j=0;
204       if( call_no<1 ) return 0;
205       byte[] buffer = new byte[size];
206       try {
207 	long start = System.currentTimeMillis();
208         for (j=1; j <= call_no; j++) {
209           test.test(buffer);
210         }
211         return (System.currentTimeMillis() - start) / (float)call_no;
212       } catch(Exception e) {
213 	log.warn("Exception when calling method 2 no. " + j, e);
214         return 0;
215       }
216     }
217 
218 
219     private float calibrate_method4(int call_no, int size) {
220       int j=0;
221       if( call_no<1 ) return 0;
222       byte[] buffer = new byte[size];
223       try {
224 	long start = System.currentTimeMillis();
225         for (j=1; j <= call_no; j++) {
226           test.mtest(buffer);
227         }
228         return (System.currentTimeMillis() - start) / (float)call_no;
229       } catch(Exception e) {
230 	log.warn("Exception when calling method 2 no. " + j, e);
231         return 0;
232       }
233     }
234 
235     
236     private float test_method1(int call_no, long pauseTime) {
237       int j=0;
238       if( call_no<1 ) return 0;
239       long reqStart, time = 0;
240       try {
241         for (j=1; j <= call_no; j++) {
242 	  reqStart = System.currentTimeMillis();
243           test.test();
244 	  time += System.currentTimeMillis() - reqStart; 
245 	  try{Thread.sleep(pauseTime); } catch(InterruptedException e) {}
246         }
247         return (float)time / call_no;
248      } catch(RemoteException e) {
249 	log.warn("Exception when calling method 2 no. " + j, e);
250         return 0;
251       }
252     }
253 
254     private float test_method2(int call_no, long pauseTime) {
255       int j=0;
256       if( call_no<1 ) return 0;
257       long reqStart, time = 0;
258       try {
259         for (j=1; j <= call_no; j++) {
260 	  reqStart = System.currentTimeMillis();
261           test.mtest();
262 	  time += System.currentTimeMillis() - reqStart; 
263 	  try{Thread.sleep(pauseTime); } catch(InterruptedException e) {}
264         }
265         return (float)time / call_no;
266      } catch(RemoteException e) {
267 	log.warn("Exception when calling method 2 no. " + j, e);
268         return 0;
269       }
270     }
271 
272     
273      private float test_method3(int call_no, long pauseTime, int size) {
274       int j=0;
275       if( call_no<1 ) return 0;
276 
277       byte[] buffer = new byte[size];
278       long reqStart, time = 0;
279       try {
280         for (j=1; j <= call_no; j++) {
281 	  reqStart = System.currentTimeMillis();
282           test.test(buffer);
283 	  time += System.currentTimeMillis() - reqStart; 
284 	  try{Thread.sleep(pauseTime); } catch(InterruptedException e) {}
285         }
286         return (float)time / call_no;
287       } catch(RemoteException e) {
288 	log.warn("Exception when calling method 2 no. " + j, e);
289         return 0;
290       }
291     }
292 
293 
294     private float test_method4(int call_no, long pauseTime, int size) {
295       int j=0;
296       if( call_no<1 ) return 0;
297 
298       byte[] buffer = new byte[size];
299       long reqStart, time = 0;
300       try {
301         for (j=1; j <= call_no; j++) {
302 	  reqStart = System.currentTimeMillis();
303           test.mtest(buffer);
304 	  time += System.currentTimeMillis() - reqStart; 
305 	  try{Thread.sleep(pauseTime); } catch(InterruptedException e) {}
306         }
307         return (float)time / call_no;
308      } catch(RemoteException e) {
309 	log.warn("Exception when calling method 2 no. " + j, e);
310         return 0;
311       }
312     }
313 } // END ClientTest