1 j.alex 1.2 //%2006////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
6 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
11 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
21 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 j.alex 1.2 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 // Author: Aruran (aruran.shanmug@in.ibm.com) & Melvin (msolomon@in.ibm.com),
33 // IBM for PEP# 241
34 // Modified By:
35 //
36 //%/////////////////////////////////////////////////////////////////////////////
37
38 #include "TestStressTestClient.h"
39
40 PEGASUS_USING_PEGASUS;
41 PEGASUS_USING_STD;
42
43 j.alex 1.2 /** Constructor - Initializes the time variables and defines the Options
44 Table.
45 */
46 TestStressTestClient::TestStressTestClient()
47 {
48 startMilliseconds = 0;
49 nowMilliseconds = 0;
50 nextCheckupInMillisecs = 0;
51 static struct OptionRow testOptionsTable[] = {
52 {"namespace", "", false, Option::STRING, 0, 0, "namespace",
53 "specifies namespace to be used for the test"},
54
55 {"classname", "", false, Option::STRING, 0, 0, "classname",
56 "specifies classname to be used for the test"},
57
58 {"verbose", "false", false, Option::BOOLEAN, 0, 0, "verbose",
59 "If set, outputs extra information "},
60
61 {"help", "false", false, Option::BOOLEAN, 0, 0, "help",
62 "Prints help message with command line options "},
63
64 j.alex 1.2 {"ssl", "false", false, Option::BOOLEAN, 0, 0, "ssl", "use SSL"},
65
66 {"username", "", false, Option::STRING, 0, 0, "username",
67 "Specifies user name"},
68
69 {"password", "", false, Option::STRING, 0, 0, "password",
70 "Specifies password"},
71
72 {"port", "", false, Option::STRING, 0, 0, "port",
73 "Port number on host"},
74
75 {"clientid", "", true, Option::STRING, 0, 0, "clientid",
76 "Client identification by controller"},
77
78 {"pidfile", "", true, Option::STRING, 0, 0, "pidfile",
79 "Client process log file"},
80
81 {"clientlog", "", true, Option::STRING, 0, 0, "clientlog",
82 "Client error log file"},
83
84 {"hostname", "", false, Option::STRING, 0, 0, "hostname",
85 j.alex 1.2 "Host name"}
86 };
87 optionCount = sizeof(testOptionsTable) / sizeof(testOptionsTable[0]);
88 optionsTable = testOptionsTable;
89 }
90 /**
91 OPTION MANAGEMENT
92 */
93
94 /** GetOptions function - This function sets up the options from
95 testOptionsTable which is initialized through constructor
96 using the option manager.
97 const char* optionName;
98 const char* defaultValue;
99 int required;
100 Option::Type type;
101 char** domain;
102 Uint32 domainSize;
103 const char* commandLineOptionName;
104 const char* optionHelpMessage;
105 */
106 j.alex 1.2 int TestStressTestClient::GetOptions(
107 OptionManager& om,
108 int& argc,
109 char** argv,
110 OptionRow* newOptionsTable, Uint32 cOptionCount)
111 {
112 char **argvv;
113 int counter = 0;
114 String argument = String::EMPTY;
115
116
117 //
118 // om.registerOptions(newOptionsTable, (const)cOptionCount);
119 //
120 om.registerOptions(newOptionsTable, cOptionCount);
121 argvv = argv;
122
123 //
124 // Following section is introduced to ignore options not
125 // required by a client.
126 //
127 j.alex 1.2 for (int i = 1; i < argc; i++)
128 {
129 argument = String::EMPTY;
130 const char* arg = argv[i];
131
132 //
133 // Check for - option.
134 //
135 if (*arg == '-')
136 {
137 //
138 // Look for the option.
139 //
140 argument.append(arg + 1);
141 const Option* option = om.lookupOption(argument);
142
143 //
144 // Get the option argument if any.
145 //
146 if (option)
147 {
148 j.alex 1.2 argvv[++counter]=argv[i];
149 if (option->getType() != Option::BOOLEAN)
150 {
151 if (i + 1 != argc)
152 {
153 argvv[++counter] = argv[++i];
154 }
155 }
156 }
157 }
158 }
159 ++counter;
160 om.mergeCommandLine(counter, argvv);
161 om.checkRequiredOptions();
162 return counter;
163 }
164
165 /** This method is used by clients to register client specific required
166 options to the option table. All these options are taken as mandatory one.
167 */
168 OptionRow *TestStressTestClient::generateClientOptions(
169 j.alex 1.2 OptionRow* clientOptionsTable,
170 Uint32 clientOptionCount,
171 Uint32& totalOptions)
172 {
173
174 Uint32 currOptionCount = 0;
175 static struct OptionRow *newOptionsTable = 0;
176
177 totalOptions = optionCount + clientOptionCount;
178
179 newOptionsTable = new struct OptionRow[totalOptions];
180
181 for (; currOptionCount < optionCount; currOptionCount++)
182 {
183 newOptionsTable[currOptionCount] = optionsTable[currOptionCount];
184 }
185 for (Uint32 i =0; i < clientOptionCount; i++)
186 {
187 newOptionsTable[currOptionCount] = clientOptionsTable[i];
188 currOptionCount++;
189 }
190 j.alex 1.2 return newOptionsTable;
191 }
192
193 /** This method is used by the clients to log information which are required
194 for controller reference. It logs the information with Client ID and
195 status of the client in the PID File log file.
196 */
197 void TestStressTestClient::logInfo(
198 String clientId,
199 pid_t clientPid,
200 int clientStatus,
201 String &pidFile)
202 {
203 char pid_str[15];
204 char status_str[15];
205 char time_str[32];
206
207 #ifdef PEGASUS_OS_TYPE_WINDOWS
208 int offset = 2;
209 #else
210 int offset = 1;
211 j.alex 1.2 #endif
212
213 //
214 // Get current time for time stamp
215 //
216 nowMilliseconds = TimeValue::getCurrentTime().toMilliseconds();
217
218 sprintf(pid_str, "%d", clientPid);
219 sprintf(status_str, "%d", clientStatus);
220 sprintf(time_str, "%" PEGASUS_64BIT_CONVERSION_WIDTH "u",
221 nowMilliseconds);
222
223 fstream pFile(pidFile.getCString(),ios::in|ios::out);
224
225 Boolean addClient= false;
226
|
260 j.alex 1.2 }
261 break;
262 }
263 }
264 if(!addClient)
265 {
266 pFile.close();
267 fstream pFile(pidFile.getCString(),ios::out|ios::app);
268 pFile<<clientId<<"::"<<clientPid<<"::"<<clientStatus<<"::"
269 <<time_str<<"\n";
270 }
271 }
272 pFile.close();
273 }
274
275 /** This method is used to take the client process start time.*/
276 void TestStressTestClient::startTime()
277 {
278 startMilliseconds = TimeValue::getCurrentTime().toMilliseconds();
279 nowMilliseconds = startMilliseconds;
280 }
281 j.alex 1.2
282 /** This method is used to check the time stamp for logging information about
283 the success or failure.
284 */
285 Boolean TestStressTestClient::checkTime()
286 {
287 nowMilliseconds = TimeValue::getCurrentTime().toMilliseconds();
288
289 if (nowMilliseconds >= nextCheckupInMillisecs)
290 {
291 nextCheckupInMillisecs = (Uint64)convertmin2millisecs(CHECKUP_INTERVAL)
292 + nowMilliseconds;
293 return true;
294 }
295 return false;
296 }
297
298 /** This method is used to log the information about the client's success or
299 failure percentage at a specific interval of time.
300 */
301 void TestStressTestClient::logErrorPercentage(
302 j.alex 1.2 Uint32 successCount,
303 Uint32 totalCount,
304 pid_t clientPid,
305 String &clientLog,
306 char client[])
307 {
308 Uint32 successPercentage, errorPercentage;
309 successPercentage = (successCount/totalCount)*100;
310 errorPercentage = 100 - successPercentage;
311
312 //
313 // loging details here
314 //
315 ofstream errorLog_File(clientLog.getCString(), ios::app);
316 errorLog_File<<client<<" PID#"<<clientPid<<" ran "<<totalCount
317 <<" times with a "<<errorPercentage<<"% failure"<<"\n";
318 errorLog_File.close();
319 }
320
321 /** This method is used to log the informations of client logs to the client
322 log file.
323 j.alex 1.2 */
324 void TestStressTestClient::errorLog(
325 pid_t clientPid,
326 String &clientLog,
327 String &message)
328 {
329 //
330 // loging details here .
331 //
332 ofstream errorLog_File(clientLog.getCString(), ios::app);
333 errorLog_File<<" PID#"<<clientPid<<"::"<<message<<"\n";
334 errorLog_File.close();
335 }
336
337 /** This method handles the SSLCertificate verification part. */
338 static Boolean verifyCertificate(SSLCertificateInfo &certInfo)
339 {
340 //
341 // Add code to handle server certificate verification.
342 //
343 return true;
344 j.alex 1.2 }
345
346 /** This method is used by the clients to connect to the server. If useSSL is
347 true then an SSL connection will be atemped with the userName and passWord
348 that is passed in. Otherwise connection will be established using
349 localhost. All parameters are required.
350 */
351 void TestStressTestClient::connectClient(
352 CIMClient *client,
353 String host,
354 Uint32 portNumber,
355 String userName,
356 String password,
357 Boolean useSSL,
358 Uint32 timeout,
359 Boolean verboseTest)
360 {
361 if (useSSL)
362 {
363 //
364 // Get environment variables.
365 j.alex 1.2 //
366 const char* pegasusHome = getenv("PEGASUS_HOME");
367
368 String trustpath = FileSystem::getAbsolutePath(
369 pegasusHome, PEGASUS_SSLCLIENT_CERTIFICATEFILE);
370
371 String randFile = String::EMPTY;
372
373 #ifdef PEGASUS_SSL_RANDOMFILE
374 randFile = FileSystem::getAbsolutePath(
375 pegasusHome,
376 PEGASUS_SSLCLIENT_RANDOMFILE);
377 #endif
378
379 SSLContext sslContext(
380 trustpath, verifyCertificate, randFile);
381 if (verboseTest)
382 {
383 cout << "connecting to " << host << ":"
384 << portNumber << " using SSL"
385 << endl;
386 j.alex 1.2 }
387 client->connect (host, portNumber, sslContext, userName, password);
388 } /* useSSL. */
389 else
390 {
391 if (verboseTest)
392 {
393 cout << "Connecting to " << host << ":" << portNumber
394 << endl;
395 }
396 client->connect (host, portNumber, userName, password);
397 }
398 if (verboseTest)
399 {
400 cout << "Client Connected" << endl;
401 }
402 }
|