1 karl 1.28 //%2006////////////////////////////////////////////////////////////////////////
|
2 chuck 1.2 //
|
3 karl 1.21 // 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 chuck 1.2 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.21 // 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 karl 1.28 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 chuck 1.2 //
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 karl 1.21 //
|
21 chuck 1.2 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // 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 // Authors: David Rosckes (rosckes@us.ibm.com)
33 // Bert Rivero (hurivero@us.ibm.com)
34 // Chuck Carmack (carmack@us.ibm.com)
35 // Brian Lucier (lucier@us.ibm.com)
36 //
37 // Modified By:
38 //
39 //%/////////////////////////////////////////////////////////////////////////////
40
41 #include <Pegasus/Common/Config.h>
42 chuck 1.2 #include <Pegasus/Common/FileSystem.h>
43 #include <stdio.h>
44 #include <iostream>
45 #include <fstream>
46 #include <string.h>
47 #include <Pegasus/Common/String.h>
48 #include <Pegasus/CQL/CQLParser.h>
49 #include <Pegasus/CQL/CQLParserState.h>
50 #include <Pegasus/CQL/CQLSelectStatement.h>
51 #include <Pegasus/Repository/RepositoryQueryContext.h>
52 #include <Pegasus/Common/CIMName.h>
|
53 chuck 1.11 #include <Pegasus/Common/MessageLoader.h>
|
54 chuck 1.2 #include <Pegasus/Repository/CIMRepository.h>
55 #include <Pegasus/Common/CIMInstance.h>
56 #include <Pegasus/Common/CIMObjectPath.h>
57
|
58 lucier 1.8 #define PEGASUS_SINT64_MIN (PEGASUS_SINT64_LITERAL(0x8000000000000000))
59 #define PEGASUS_UINT64_MAX PEGASUS_UINT64_LITERAL(0xFFFFFFFFFFFFFFFF)
|
60 lucier 1.12 #define PEGASUS_SINT64_MAX (PEGASUS_SINT64_LITERAL(0x7FFFFFFFFFFFFFFF))
|
61 lucier 1.8
|
62 chuck 1.2 PEGASUS_USING_PEGASUS;
63 PEGASUS_USING_STD;
64 int CQL_parse();
65
|
66 david 1.10 Boolean cqlcli_verbose = false;
67
|
68 lucier 1.8 void hackInstances(Array<CIMInstance>& instances)
69 {
70 for (Uint32 i=0; i < instances.size(); i++)
71 {
72 CIMInstance inst = instances[i];
73 // Only hack it if it is an instance of CQL_TestPropertyTypes
74 if (inst.getClassName() == "CQL_TestPropertyTypes")
75 {
76 // The properties which the mof compiler messes up will be removed and added manually.
77 // Start with Instance #1
78 Uint64 instID;
79 inst.getProperty(inst.findProperty("InstanceID")).getValue().get(instID);
80 if (instID == 1)
81 {
|
82 lucier 1.12 // The stupid mof compiler loses the negative on floats.
|
83 lucier 1.8 // PropertyReal32 = -32.0
84 inst.removeProperty(inst.findProperty("PropertyReal32"));
85 Real32 real32Val = -32.0;
86 inst.addProperty(CIMProperty("PropertyReal32", CIMValue(real32Val)));
|
87 lucier 1.12
88 // PropertySint64Lower = -9223372036854775808
89 inst.removeProperty(inst.findProperty("PropertySint64Lower"));
90 Sint64 sint64Val = PEGASUS_SINT64_MIN;
91 inst.addProperty(CIMProperty("PropertySint64Lower", CIMValue(sint64Val)));
92
93 // PropertySint64Upper = 9223372036854775807
94 inst.removeProperty(inst.findProperty("PropertySint64Upper"));
95 sint64Val = PEGASUS_SINT64_MAX;
96 inst.addProperty(CIMProperty("PropertySint64Upper", CIMValue(sint64Val)));
|
97 lucier 1.8 }
98 // Then do Instance #2
99 else if (instID == 2)
100 {
101 }
102 }
103 }
104 }
105
|
106 chuck 1.14 String getStatementString(const String& stmt)
107 {
108 // Returns the select statement string, but takes
109 // non-ascii chars (> 0x7f) into account by turning
110 // them into hex strings.
111 // This is needed because some tests contain
112 // non-ascii in their select statements, and we
113 // want a consistent output on all platforms.
114 String res;
115
116 for (Uint32 i = 0, n = stmt.size(); i < n; i++)
117 {
118 Uint16 code = stmt[i];
119
120 if (code <= PEGASUS_MAX_PRINTABLE_CHAR)
121 {
122 res.append((char)code);
123 }
124 else
125 {
126 // turn into hex format:
127 chuck 1.14 char hex[8];
128 sprintf(hex, "\\x%04X", code);
129 res.append(hex);
130 }
131 }
132
133 return res;
134 }
135
|
136 lucier 1.8
|
137 chuck 1.3 void printProperty(CIMProperty& prop, Uint32 propNum, String& prefix)
138 {
139 // Recursive function to handle embedded object trees
140
141 cout << prefix << "Prop #" << propNum << " Name = " << prop.getName().getString();
142
143 CIMValue val = prop.getValue();
144
|
145 a.dunfey 1.29 #ifdef PEGASUS_EMBEDDED_INSTANCE_SUPPORT
146 CIMType valType = val.getType();
147 if (valType != CIMTYPE_OBJECT && valType != CIMTYPE_INSTANCE)
148 #else
|
149 chuck 1.3 if (val.getType() != CIMTYPE_OBJECT)
|
150 a.dunfey 1.29 #endif // PEGASUS_EMBEDDED_INSTANCE_SUPPORT
|
151 chuck 1.3 {
152 // Not embedded object
153 if (val.isNull())
154 {
155 cout << ", Value = NULL" << endl;
156 }
157 else
158 {
159 cout << ", Value = " << val.toString() << endl;
160 }
161 }
162 else
163 {
164 // Embedded object, or array of objects
165 Array<CIMObject> embObjs;
|
166 a.dunfey 1.29 #ifdef PEGASUS_EMBEDDED_INSTANCE_SUPPORT
|
167 chuck 1.3 if (val.isArray())
168 {
|
169 a.dunfey 1.29 if(valType == CIMTYPE_INSTANCE)
170 {
171 Array<CIMInstance> embInsts;
172 val.get(embInsts);
173 int instCount = embInsts.size();
174 for(int i = 0; i < instCount; i++)
175 {
176 embObjs.append((CIMObject)embInsts[i]);
177 }
178 }
179 else
180 {
181 val.get(embObjs);
182 }
183 }
184 else
185 {
186 if(valType == CIMTYPE_INSTANCE)
187 {
188 CIMInstance tmpInst;
189 val.get(tmpInst);
190 a.dunfey 1.29 embObjs.append((CIMObject)tmpInst);
191 }
192 else
193 {
194 CIMObject tmpObj;
195 val.get(tmpObj);
196 embObjs.append(tmpObj);
197 }
198 }
199 #else
200 if (val.isArray())
201 {
202 val.get(embObjs);
|
203 chuck 1.3 }
204 else
205 {
|
206 a.dunfey 1.29 CIMObject tmpObj;
207 val.get(tmpObj);
208 embObjs.append(tmpObj);
|
209 chuck 1.3 }
|
210 a.dunfey 1.29 #endif // PEGASUS_EMBEDDED_INSTANCE_SUPPORT
|
211 chuck 1.3
212 for (Uint32 j = 0; j < embObjs.size(); j++)
213 {
214 CIMObject embObj = embObjs[j];
215 if (embObj.isClass())
216 {
217 // Embedded class
218 CIMClass embCls(embObj);
219 cout << ", Value = class of " << embCls.getClassName().getString() << endl;
220 }
221 else
222 {
223 // Embedded instance, need to recurse on each property
224 CIMInstance embInst(embObj);
225
226 String newPrefix = prefix;
227 newPrefix.append(prefix);
228
229 cout << endl << newPrefix << "Instance of class " << embInst.getClassName().getString() << endl;
230
231 Uint32 cnt = embInst.getPropertyCount();
232 chuck 1.3 if (cnt == 0)
233 {
234 cout << newPrefix << "No properties left after projection" << endl;
235 }
236
|
237 chuck 1.11 if (cnt > 10 && !cqlcli_verbose)
|
238 chuck 1.3 {
|
239 chuck 1.11 cout << newPrefix << "Instance has " << cnt << " properties" << endl;
240 }
241 else
242 {
243 for (Uint32 n = 0; n < cnt; n++)
244 {
245 CIMProperty prop = embInst.getProperty(n);
246 printProperty(prop, n, newPrefix);
247 }
|
248 chuck 1.3 }
249 }
250 }
251 }
252 }
253
|
254 chuck 1.2 Boolean _applyProjection(Array<CQLSelectStatement>& _statements,
255 Array<CIMInstance>& _instances,
256 String testOption)
257 {
258 if(testOption == String::EMPTY || testOption == "2")
259 {
260 cout << "========Apply Projection Results========" << endl;
261
262 for(Uint32 i = 0; i < _statements.size(); i++)
263 {
|
264 chuck 1.3 cout << "======================================" << i << endl;
|
265 chuck 1.2 cout << _statements[i].toString() << endl;
266
267 for(Uint32 j = 0; j < _instances.size(); j++)
268 {
269 cout << "Instance of class " << _instances[j].getClassName().getString() << endl;
270
271 try
272 {
273 CIMInstance projInst = _instances[j].clone();
274
275 // Remove the property "MissingProperty" for the
276 // testcases that depend on the property being missing.
277 Uint32 missing = projInst.findProperty("MissingProperty");
278 if (missing != PEG_NOT_FOUND)
279 {
280 projInst.removeProperty(missing);
281 }
282
|
283 chuck 1.27 CIMInstance cloneInst = projInst.clone();
284 Boolean gotPropExc = false;
285 try
286 {
287 _statements[i].applyProjection(projInst, false);
288 }
289 catch (QueryRuntimePropertyException & qrpe)
290 {
291 // Got a missing property exception.
292 cout << "-----" << qrpe.getMessage() << endl;
293 gotPropExc = true;
294 }
295
296 if (gotPropExc)
297 {
298 // Got a missing property exception.
299 // Try again, allowing missing properties.
300 // Need to use a cloned instance because the original instance
301 // was partially projected.
302 cout << "Instance of class " << _instances[j].getClassName().getString()
303 << ". Allow missing properties." << endl;
304 chuck 1.27 projInst = cloneInst;
305 _statements[i].applyProjection(projInst, true);
306 }
|
307 chuck 1.2
308 Uint32 cnt = projInst.getPropertyCount();
309 if (cnt == 0)
310 {
311 cout << "-----No properties left after projection" << endl;
312 }
313
|
314 chuck 1.3 String prefix("-----");
|
315 chuck 1.11
316 if (cnt > 10 && !cqlcli_verbose)
|
317 chuck 1.2 {
|
318 chuck 1.11 cout << "-----Instance has " << cnt << " properties" << endl;
319 }
320 else
321 {
322 for (Uint32 n = 0; n < cnt; n++)
323 {
324 CIMProperty prop = projInst.getProperty(n);
325 printProperty(prop, n, prefix);
326 }
|
327 chuck 1.2 }
328 }
329 catch(Exception& e){ cout << "-----" << e.getMessage() << endl;}
330 catch(...){ cout << "Unknown Exception" << endl;}
331 }
332 }
333 }
334
335 return true;
336 }
337
338 Boolean _validateProperties(Array<CQLSelectStatement>& _statements,
339 Array<CIMInstance>& _instances,
340 String testOption)
341 {
342 if(testOption == String::EMPTY || testOption == "4")
343 {
344 cout << "======Validate Properties Results=======" << endl;
345
346 for(Uint32 i = 0; i < _statements.size(); i++)
347 {
|
348 chuck 1.3 cout << "======================================" << i << endl;
|
349 chuck 1.2 cout << _statements[i].toString() << endl;
350
351 try
352 {
353 _statements[i].validate();
354 cout << "----- validate ok" << endl;
355 }
356 catch(Exception& e){ cout << "-----" << e.getMessage() << endl;}
357 catch(...){ cout << "Unknown Exception" << endl;}
358 }
359 }
360
361 return true;
362 }
363
364 void _printPropertyList(CIMPropertyList& propList)
365 {
366 if (propList.isNull())
367 {
368 cout << "-----all properties required" << endl;
369 }
370 chuck 1.2 else if (propList.size() == 0)
371 {
372 cout << "-----no properties required" << endl;
373 }
374 else
375 {
376 for (Uint32 n = 0; n < propList.size(); n++)
377 {
378 cout << "-----Required property " << propList[n].getString() << endl;
379 }
380 }
381 }
382
383 Boolean _getPropertyList(Array<CQLSelectStatement>& _statements,
384 Array<CIMInstance>& _instances,
385 CIMNamespaceName ns,
386 String testOption)
387 {
388 if(testOption == String::EMPTY || testOption == "3")
389 {
390 cout << "========Get Property List Results=======" << endl;
391 chuck 1.2
|
392 chuck 1.11 CIMPropertyList propList;
393
|
394 chuck 1.2 for(Uint32 i = 0; i < _statements.size(); i++)
395 {
|
396 chuck 1.3 cout << "======================================" << i << endl;
|
397 chuck 1.2 cout << _statements[i].toString() << endl;
398
|
399 chuck 1.11 try
|
400 chuck 1.2 {
|
401 chuck 1.11 cout << endl << "Get Class Path List" << endl;
402 Array<CIMObjectPath> fromPaths = _statements[i].getClassPathList();
403 for (Uint32 k = 0; k < fromPaths.size(); k++)
404 {
405 cout << "-----" << fromPaths[k].toString() << endl;
406 }
407 }
408 catch(Exception& e){ cout << "-----" << e.getMessage() << endl;}
409 catch(...){ cout << "Unknown Exception" << endl;}
410
411 try
412 {
413 cout << "SELECT Chained Identifiers" << endl;
414 Array<CQLChainedIdentifier> selIds = _statements[i].getSelectChainedIdentifiers();
415 for (Uint32 k = 0; k < selIds.size(); k++)
416 {
417 cout << "-----" << selIds[k].toString() << endl;
418 }
419 }
420 catch(Exception& e){ cout << "-----" << e.getMessage() << endl;}
421 catch(...){ cout << "Unknown Exception" << endl;}
422 chuck 1.11
423 try
424 {
425 cout << "WHERE Chained Identifiers" << endl;
426 Array<CQLChainedIdentifier> whereIds = _statements[i].getWhereChainedIdentifiers();
427 if (whereIds.size() == 0)
428 {
429 cout << "-----none" << endl;
430 }
431 for (Uint32 k = 0; k < whereIds.size(); k++)
|
432 chuck 1.2 {
|
433 chuck 1.11 cout << "-----" << whereIds[k].toString() << endl;
|
434 chuck 1.2 }
|
435 chuck 1.11 }
436 catch(Exception& e){ cout << "-----" << e.getMessage() << endl;}
437 catch(...){ cout << "Unknown Exception" << endl;}
438
439 try
440 {
441 cout << "Property List for the FROM class " << endl;
442 propList.clear();
443 propList = _statements[i].getPropertyList();
444 _printPropertyList(propList);
445 }
446 catch(Exception& e){ cout << "-----" << e.getMessage() << endl;}
447 catch(...){ cout << "Unknown Exception" << endl;}
|
448 chuck 1.2
|
449 chuck 1.11 try
450 {
451 cout << "SELECT Property List for the FROM class " << endl;
452 propList.clear();
453 propList = _statements[i].getSelectPropertyList();
454 _printPropertyList(propList);
455 }
456 catch(Exception& e){ cout << "-----" << e.getMessage() << endl;}
457 catch(...){ cout << "Unknown Exception" << endl;}
|
458 chuck 1.2
|
459 chuck 1.11 try
460 {
461 cout << "WHERE Property List for the FROM class " << endl;
462 propList.clear();
463 propList = _statements[i].getWherePropertyList();
464 _printPropertyList(propList);
465 }
466 catch(Exception& e){ cout << "-----" << e.getMessage() << endl;}
467 catch(...){ cout << "Unknown Exception" << endl;}
|
468 chuck 1.2
|
469 chuck 1.11 // Build a list of unique class names from the instances
470 Array<CIMName> classNames;
471 for(Uint32 j = 0; j < _instances.size(); j++)
472 {
473 Boolean found = false;
474 for(Uint32 k = 0; k < classNames.size(); k++)
475 {
476 if (_instances[j].getClassName() == classNames[k])
|
477 chuck 1.2 {
|
478 chuck 1.11 found = true;
|
479 chuck 1.2 }
480 }
481
|
482 chuck 1.11 if (!found)
483 {
484 classNames.append(_instances[j].getClassName());
|
485 chuck 1.2 }
|
486 chuck 1.11 }
487
488 for(Uint32 j = 0; j < classNames.size(); j++)
489 {
490 CIMName className = classNames[j];
491 CIMObjectPath classPath (String::EMPTY,
492 ns,
493 className);
|
494 chuck 1.2
495 try
496 {
497 cout << "Property List for " << className.getString() << endl;
|
498 chuck 1.11 propList.clear();
499 propList = _statements[i].getPropertyList(classPath);
|
500 chuck 1.2 _printPropertyList(propList);
501 }
502 catch(Exception& e){ cout << "-----" << e.getMessage() << endl;}
503 catch(...){ cout << "Unknown Exception" << endl;}
504
505 try
506 {
507 cout << "SELECT Property List for " << className.getString() << endl;
508 propList.clear();
509 propList = _statements[i].getSelectPropertyList(classPath);
510 _printPropertyList(propList);
511 }
512 catch(Exception& e){ cout << "-----" << e.getMessage() << endl;}
513 catch(...){ cout << "Unknown Exception" << endl;}
514
515 try
516 {
517 cout << "WHERE Property List for " << className.getString() << endl;
518 propList.clear();
519 propList = _statements[i].getWherePropertyList(classPath);
520 _printPropertyList(propList);
521 chuck 1.2 }
522 catch(Exception& e){ cout << "-----" << e.getMessage() << endl;}
523 catch(...){ cout << "Unknown Exception" << endl;}
524 }
525 }
526 }
527
528 return true;
529 }
530
531 Boolean _evaluate(Array<CQLSelectStatement>& _statements,
532 Array<CIMInstance>& _instances,
533 String testOption)
534 {
|
535 chuck 1.14 // Not liking how the mof compiler is working with CQL_TestPropertyTypes,
536 // so I am going to hack the instances so that they have the values
537 // I need for the function tests.
|
538 lucier 1.8 hackInstances(_instances);
539
|
540 chuck 1.2 if(testOption == String::EMPTY || testOption == "1")
|
541 humberto 1.4 {
542 cout << "=========Evaluate Query==============" << endl;
|
543 chuck 1.2 for(Uint32 i = 0; i < _statements.size(); i++)
544 {
|
545 lucier 1.8 cout << "========= " << i << " =========" << endl;
|
546 chuck 1.14 cout << "-----Query: " << getStatementString(_statements[i].toString()) << endl << endl;;
|
547 chuck 1.2
548 for(Uint32 j = 0; j < _instances.size(); j++)
549 {
550 try
551 {
|
552 humberto 1.5 cout << "-----Instance: " << _instances[j].getPath().toString() << endl;
|
553 chuck 1.2 Boolean result = _statements[i].evaluate(_instances[j]);
|
554 david 1.10
|
555 chuck 1.14 if(cqlcli_verbose)
556 {
557 cout << "Inst # " << j << ": " << _statements[i].toString() << " = ";
558 }
|
559 humberto 1.17 if(result) cout << "TRUE" << endl;
560 else cout << "FALSE" << endl;
|
561 chuck 1.2 }
|
562 lucier 1.13 catch(Exception e)
563 {
564 if (cqlcli_verbose)
565 cout << "ERROR! -- " << _statements[i].toString() << endl << e.getMessage() << endl << endl;
566 else
567 cout << "ERROR!" << endl << e.getMessage() << endl << endl;
568 }
|
569 chuck 1.2 catch(...){ cout << "Unknown Exception" << endl;}
570 }
571 }
572 }
573
574 return true;
575 }
576
577 Boolean _normalize(Array<CQLSelectStatement>& _statements,
578 Array<CIMInstance>& _instances,
579 String testOption)
580 {
581 if(testOption == String::EMPTY || testOption == "5")
582 {
583 cout << "=========Normalize Results==============" << endl;
584
585 for(Uint32 i = 0; i < _statements.size(); i++)
586 {
|
587 chuck 1.3 cout << "======================================" << i << endl;
|
588 chuck 1.2
589 try
590 {
591 cout << "-----Statement before normalize" << endl;
592 _statements[i].applyContext();
593 cout << _statements[i].toString() << endl;
594
595 _statements[i].normalizeToDOC();
596 cout << "-----Statement after normalize" << endl;
597 cout << _statements[i].toString() << endl;
598
599 cout << "-----Traversing the predicates" << endl;
600 CQLPredicate topPred = _statements[i].getPredicate();
601 if (topPred.isSimple())
602 {
603 cout << "-----Top predicate is simple: " << topPred.toString() << endl;
604 }
605 else
606 {
607 cout << "-----Top predicate is not simple: " << topPred.toString() << endl;
|
608 humberto 1.20 if( topPred.getInverted() )
609 cout << "-----ERROR - Top predicate is inverted: " << topPred.toString() << endl;
|
610 chuck 1.2
611 Array<CQLPredicate> secondLevelPreds = topPred.getPredicates();
612 for (Uint32 n = 0; n < secondLevelPreds.size(); n++)
613 {
614 if (secondLevelPreds[n].isSimple())
615 {
616 cout << "-----2nd level predicate is simple: "
617 << secondLevelPreds[n].toString() << endl;
618 }
619 else
620 {
|
621 humberto 1.20 if( secondLevelPreds[n].getInverted() )
622 cout << "-----ERROR - 2nd level predicate is inverted: " << secondLevelPreds[n].toString() << endl;
|
623 chuck 1.2 cout << "-----ERROR - 2nd level predicate is NOT simple!: "
624 << secondLevelPreds[n].toString() << endl;
625 }
626 }
627 }
628 }
629 catch(Exception& e){ cout << "-----" << e.getMessage() << endl;}
630 catch(...){ cout << "Unknown Exception" << endl;}
631 }
632 }
633
634 return true;
635 }
636
637 void buildEmbeddedObjects(CIMNamespaceName& ns,
638 Array<CIMInstance>& instances,
639 CIMRepository* rep)
640 {
641
642 //
643 // Sort out the instances of CQL_TestElement, CQL_TestPropertyTypes,
644 chuck 1.2 // CIM_ComputerSystem that will be added as embedded objects to
645 // the embedded object test class
646 //
647
648 CIMName nameTE("CQL_TestElement");
649 CIMName instIdName("InstanceId");
650 CIMName nameTPT("CQL_TestPropertyTypes");
651 CIMName nameCS("CIM_ComputerSystem");
652
653 CIMInstance testElem;
654 Array<CIMObject> testElemArray;
655 Boolean foundTestElem = false;
656
657 CIMInstance testCS;
658 Boolean foundCS = false;
659
660 Array<CIMObject> testPropTypesArray;
661
662 for (Uint32 i = 0; i < instances.size(); i++)
663 {
|
664 chuck 1.3 // Find the CQL_TestElement with InstanceId = 0
|
665 chuck 1.2 if (instances[i].getClassName() == nameTE)
666 {
667 Uint32 index = instances[i].findProperty(instIdName);
668 if (index == PEG_NOT_FOUND)
669 {
670 throw Exception("Error building embedded objects. CQL_TestElement with InstanceId prop not found");
671 }
672
673 Uint64 instId;
674 instances[i].getProperty(index).getValue().get(instId);
675 if (instId == 0)
676 {
|
677 chuck 1.3 // Found the CQL_TestElement with InstanceId = 0.
678 // Change to InstanceId to 10, and save it.
|
679 chuck 1.2 foundTestElem = true;
|
680 chuck 1.3 instances[i].removeProperty(index);
681 instances[i].addProperty(CIMProperty(instIdName, CIMValue((Uint64)10)));
|
682 chuck 1.2 testElem = instances[i].clone();
683 }
684 }
685
686 // Save the CQL_TestPropertyType instances as we find them
687 if (instances[i].getClassName() == nameTPT)
688 {
689 testPropTypesArray.append(instances[i].clone());
690 }
691
692 // Save the CIM_ComputerSystem instance
693 if (instances[i].getClassName() == nameCS)
694 {
695 foundCS = true;
696 testCS = instances[i].clone();
|
697 chuck 1.3
698 // Remove the PrimaryOwnerName property so that apply projection
699 // using the wildcard will fail
700 Uint32 tmpIdx = testCS.findProperty("PrimaryOwnerName");
701 if (tmpIdx != PEG_NOT_FOUND)
702 {
703 testCS.removeProperty(tmpIdx);
704 }
|
705 chuck 1.2 }
706 }
707
708 if (!foundTestElem)
709 {
710 throw Exception("Error building embedded objects. CQL_TestElement with InstanceId = 0 not found");
711 }
712
713 if (!foundCS)
714 {
715 throw Exception("Error building embedded objects. CIM_ComputerSystem not found");
716 }
717
718 if (testPropTypesArray.size() <= 1)
719 {
720 throw Exception("Error building embedded objects. Not enough CQL_TestPropertyTypes found");
721 }
722
723 //
724 // Now build the array of CQL_TestElement (see below for why we are doing this)
725 //
726 chuck 1.2
727 testElemArray.append(testElem.clone());
728
729 Uint32 index = testElem.findProperty(instIdName);
730 testElem.removeProperty(index);
|
731 chuck 1.3 testElem.addProperty(CIMProperty(instIdName, CIMValue((Uint64)11)));
|
732 chuck 1.2 testElemArray.append(testElem.clone());
733
734 index = testElem.findProperty(instIdName);
735 testElem.removeProperty(index);
|
736 chuck 1.3 testElem.addProperty(CIMProperty(instIdName, CIMValue((Uint64)12)));
|
737 chuck 1.2 testElemArray.append(testElem.clone());
738
739 //
740 // Get the class that will be added as an embedded object
741 //
742
743 CIMClass someClass = rep->getClass(ns,
744 "CIM_Process",
745 false, // local only
746 true, // include quals
747 true); // include class origin
748
749 // Build the embedded object structure.
750 //
751 // The structure looks like this:
752 //
753 // class CQL_EmbeddedSubClass is subclass of CQL_EmbeddedBase
754 // class CQL_EmbeddedTestPropertyTypes is subclass of CQL_EmbeddedTestElement
755 //
756 // instance of CQL_EmbeddedSubClass
757 //
758 chuck 1.2 // property InstanceID has value 100
759 //
760 // property EmbObjBase has
761 // instance of CQL_EmbeddedTestElement
762 // property InstanceID has value 1000
763 // property TEArray has array of instance of CQL_TestElement
|
764 chuck 1.3 // the array elements have InstanceID properties
765 // set to 10, 11, 12
|
766 chuck 1.2 // property TE has instance of CQL_TestElement
|
767 chuck 1.3 // property InstanceID has value 10
|
768 chuck 1.2 // property CS has instance of CIM_ComputerSystem
|
769 chuck 1.3 // note that the PrimaryOwnerName property is removed
|
770 chuck 1.2 // property SomeClass has class of CIM_Process
771 // property SomeString has a string
772 //
773 // property EmbObjSub has
|
774 lucier 1.12 // instance of CQL_EmbeddedTestPropertyTypes
|
775 chuck 1.2 // property InstanceID has value 1001
776 // property TEArray has array of instance of CQL_TestElement
|
777 chuck 1.3 // the array elements have InstanceID properties
778 // set to 10, 11, 12
|
779 chuck 1.2 // property TE has instance of CQL_TestElement
|
780 chuck 1.3 // property InstanceID has value 10
|
781 chuck 1.2 // property CS has instance of CIM_ComputerSystem
|
782 chuck 1.3 // note that the PrimaryOwnerName property is removed
|
783 chuck 1.2 // property TPTArray has array of instance of CQL_TestPropertyTypes
784 // the array is built from the instances compiled in the repository
785 // property TPT has instance of CQL_TestPropertyTypes
|
786 chuck 1.3 // this instance is the first instance found in the repository
|
787 chuck 1.2 // property SomeClass has class of CIM_Process
|
788 chuck 1.3 // property SomeString has a string
|
789 chuck 1.2 // property SomeUint8 has a uint8
790 //
791 CIMInstance embTE("CQL_EmbeddedTestElement");
792 embTE.addProperty(CIMProperty("InstanceID", CIMValue((Uint64)1000)));
793 embTE.addProperty(CIMProperty("TEArray", CIMValue(testElemArray)));
794 CIMObject _obj1 = testElemArray[0];
|
795 chuck 1.3 CIMValue testElemVal(_obj1);
796 embTE.addProperty(CIMProperty("TE", testElemVal));
797 CIMValue csVal(testCS);
798 embTE.addProperty(CIMProperty("CS", csVal));
|
799 chuck 1.2 embTE.addProperty(CIMProperty("SomeClass", CIMValue(someClass)));
|
800 chuck 1.3 embTE.addProperty(CIMProperty("SomeString", CIMValue(String("Huh?"))));
|
801 chuck 1.2
802 CIMInstance embTPT("CQL_EmbeddedTestPropertyTypes");
803 embTPT.addProperty(CIMProperty("InstanceID", CIMValue((Uint64)1001)));
|
804 chuck 1.3 embTPT.addProperty(CIMProperty("TEArray", CIMValue(testElemArray)));
805 embTPT.addProperty(CIMProperty("TE", testElemVal));
806 embTPT.addProperty(CIMProperty("CS", csVal));
|
807 chuck 1.2 embTPT.addProperty(CIMProperty("TPTArray", CIMValue(testPropTypesArray)));
|
808 chuck 1.3 embTPT.addProperty(CIMProperty("TPT", CIMValue(testPropTypesArray[0])));
|
809 chuck 1.2 embTPT.addProperty(CIMProperty("SomeClass", CIMValue(someClass)));
|
810 chuck 1.3 embTPT.addProperty(CIMProperty("SomeString", CIMValue(String("What?"))));
|
811 chuck 1.2 embTPT.addProperty(CIMProperty("SomeUint8", CIMValue((Uint8)3)));
812
813 CIMInstance embSub("CQL_EmbeddedSubClass");
814 embSub.addProperty(CIMProperty("InstanceID", CIMValue((Uint64)100)));
815 embSub.addProperty(CIMProperty("EmbObjBase", CIMValue(embTE)));
816 embSub.addProperty(CIMProperty("EmbObjSub", CIMValue(embTPT)));
817
|
818 chuck 1.3 instances.clear();
|
819 chuck 1.2 instances.append(embSub);
820 }
821
|
822 chuck 1.22 void sortInstances(Array<CIMInstance>& x)
823 {
824 Uint32 n = x.size();
825
826 if (n < 2)
827 return;
828
829 for (Uint32 i = 0; i < n - 1; i++)
830 {
831 for (Uint32 j = 0; j < n - 1; j++)
832 {
833 // This is not quite a lexigraphical sort because
834 // CQL_TestPropertyTypesMissing will sort before
835 // CQL_TestPropertyTypes. It was done this way
836 // so that the .resgood files don't need to change.
837
838 String str1 = x[j].getClassName().getString();
839 String str2 = x[j+1].getClassName().getString();
840
841 Uint32 sz1 = str1.size();
842 Uint32 sz2 = str2.size();
843 chuck 1.22
844 if (sz1 > sz2)
845 {
846 str1.remove(sz2);
847 }
848 else if (sz2 > sz1)
849 {
850 str2.remove(sz1);
851 }
852
853 int comp = String::compareNoCase(str1, str2);
854 if ((comp == 0 && sz2 > sz1) || comp > 0)
855 {
856 CIMInstance t = x[j];
857 x[j] = x[j+1];
858 x[j+1] = t;
859 }
860 }
861 }
862 }
|
863 lucier 1.8
864 Boolean populateInstances(Array<CIMInstance>& _instances, String& className, CIMNamespaceName& _ns, CIMRepository* _rep)
865 {
866 String embSubName("CQL_EmbeddedSubClass");
867 String embBaseName("CQL_EmbeddedBase");
|
868 lucier 1.9
869 // IF the class is CIM_RunningOS, then we will setup some references to CIM_ComputerSystem
870 if (className == "CIM_RunningOS")
871 {
872 Array<CIMInstance> cSystems;
873 const CIMName CSClass(String("CIM_ComputerSystem"));
874
875 try
876 {
|
877 kumpf 1.31 cSystems.appendArray(_rep->enumerateInstancesForClass( _ns, CSClass));
|
878 lucier 1.9 }
879 catch(Exception& e)
880 {
|
881 chuck 1.22 cout << endl << endl << "Exception: Invalid namespace/class: " <<
882 e.getMessage() << endl << endl;
|
883 lucier 1.9 return false;
884 }
885
|
886 chuck 1.14 // For every computer system instance, make a runningOS that has a reference to it.
887 //The RunningOS will be the instance that is stored.
|
888 lucier 1.9 for (Uint32 i=0; i < cSystems.size(); i++)
889 {
890 CIMInstance runOS("CIM_RunningOS");
891 runOS.addProperty(CIMProperty("Dependent", CIMValue(cSystems[i].getPath())));
892
893 _instances.append(runOS);
894 }
895 return true;
896 }
|
897 lucier 1.8
898 if(className != String::EMPTY && className != embSubName && className != embBaseName)
899 {
900 // If the classname was specified, and was not an embedded object class, then
901 // load its instances from the repository.
902 try
903 {
904 const CIMName _testclass(className);
|
905 kumpf 1.31 _instances = _rep->enumerateInstancesForSubtree( _ns, _testclass, true ); // deep inh true
|
906 chuck 1.22
907 // Sort the CQL instances to avoid the class ordering problem that happens
908 // because the order depends on how the file system orders the class files
909 // in the repository.
910 sortInstances(_instances);
|
911 lucier 1.8 }
912 catch(Exception& e){
913 cout << endl << endl << "Exception: Invalid namespace/class: " << e.getMessage() << endl << endl;
914 return false;
915 }
916 }
917 else
918 {
919 // load all the non-embedded instances we support
920 cout << endl << "Using default class names to test queries. " << endl << endl;
921 const CIMName _testclass1(String("CQL_TestElement"));
922 const CIMName _testclass2(String("CIM_ComputerSystem"));
923 try
924 {
925 // Deep inh = true for CQL_TestElement to also get CQL_TestPropertyTypes
926 // and CQL_TestPropertyTypesMissing
|
927 kumpf 1.31 _instances = _rep->enumerateInstancesForSubtree( _ns, _testclass1, true ); // deep inh true
|
928 lucier 1.8
|
929 chuck 1.22 // Sort the CQL instances to avoid the class ordering problem that happens
930 // because the order depends on how the file system orders the class files
931 // in the repository.
932 // NOTE - do not sort the CIM_ComputerSystem because the resgood files expect
933 // the CIM_ComputerSystem to be after the CQL instances.
934 sortInstances(_instances);
935
|
936 kumpf 1.31 // only get the CIM_ComputerSystem
937 _instances.appendArray(_rep->enumerateInstancesForClass( _ns, _testclass2));
|
938 lucier 1.8 }
939 catch(Exception& e)
940 {
941 cout << endl << endl << "Exception: Invalid namespace/class: " << e.getMessage() << endl << endl;
942 return false;
943 }
944
945 if (className == embSubName || className == embBaseName)
946 {
947 // If the embedded object classname was specified, then build its instances.
948 // Note: this will remove the other instances from the array.
949 buildEmbeddedObjects(_ns,
950 _instances,
951 _rep);
952 }
953 }
954 return true;
955 }
956
|
957 chuck 1.2 void help(const char* command){
958 cout << command << " queryFile [option]" << endl;
959 cout << " options:" << endl;
960 cout << " -test: ";
961 cout << "1 = evaluate" << endl
|
962 chuck 1.3 << " 2 = apply projection" << endl
963 << " 3 = get property list" << endl;
|
964 chuck 1.2 cout << " 4 = validate properties" << endl;
965 cout << " 5 = normalize to DOC" << endl;
966 cout << " -className class" << endl;
|
967 chuck 1.11 cout << " -nameSpace namespace (Example: root/SampleProvider)" << endl;
968 cout << " -verbose" << endl << endl;
|
969 chuck 1.2 }
970
971 int main(int argc, char ** argv)
972 {
|
973 lucier 1.8 // process options
|
974 chuck 1.2 if(argc == 1 || (argc > 1 && strcmp(argv[1],"-h") == 0) ){
975 help(argv[0]);
976 exit(0);
977 }
978
|
979 chuck 1.11 // Since the output of this program will be compared with
|
980 chuck 1.14 // a master output file, and the master file will have default
981 // messages, turn off ICU message loading.
|
982 chuck 1.11 MessageLoader::_useDefaultMsg = true;
983
|
984 lucier 1.8 String testOption;
985 String className = String::EMPTY;
986 String nameSpace;
987
988 for(int i = 0; i < argc; i++){
989 if((strcmp(argv[i],"-test") == 0) && (i+1 < argc))
990 testOption = argv[i+1];
991 if((strcmp(argv[i],"-className") == 0) && (i+1 < argc))
992 className = argv[i+1];
993 if((strcmp(argv[i],"-nameSpace") == 0) && (i+1 < argc))
994 nameSpace = argv[i+1];
|
995 chuck 1.14 if((strcmp(argv[i],"-verbose") == 0))
|
996 david 1.10 cqlcli_verbose = true;
|
997 lucier 1.8 }
998
|
999 humberto 1.18 { // necessary when testing with Purifty so that _statements goes out of scope before the program exits
|
1000 lucier 1.8 Array<CQLSelectStatement> _statements;
|
1001 david 1.10
|
1002 chuck 1.3
|
1003 lucier 1.8 // setup test environment
|
1004 jim.wunderlich 1.26
1005 // get the configuration variable PEGASUS_HOME
1006 const char* peg_home = getenv("PEGASUS_HOME");
1007
1008 // get the makefile build config variable REPOSITORY_NAME
1009 const char* repo_name = getenv("REPOSITORY_NAME");
1010
1011
1012 if (peg_home == NULL)
1013 exit(-1);
1014
1015 if (repo_name == NULL)
1016 repo_name = "repository";
1017
1018
1019 String repositoryDir(peg_home);
1020 repositoryDir.append("/");
1021 repositoryDir.append(repo_name);
1022
|
1023 humberto 1.18 //
|
1024 jim.wunderlich 1.26 // Comment out the above 3 lines and umcomment the line below when testing with Rational Purify
|
1025 humberto 1.18 //
1026
1027 //String repositoryDir("c:/pegasus-cvs/pegasus");
1028
|
1029 jim.wunderlich 1.26
|
1030 lucier 1.8
1031 CIMNamespaceName _ns;
1032 if(nameSpace != String::EMPTY){
1033 _ns = nameSpace;
1034 }else{
1035 cout << "Using root/SampleProvider as default namespace." << endl;
1036 _ns = String("root/SampleProvider");
1037 }
1038
1039 CIMRepository* _rep = new CIMRepository(repositoryDir);
1040 RepositoryQueryContext _ctx(_ns, _rep);
1041 String lang("CIM:CQL");
1042 String query("dummy statement");
1043 CQLSelectStatement _ss(lang,query,_ctx);
1044 if (_ss.getQuery() != query || _ss.getQueryLanguage() != lang)
1045 {
1046 cout << "ERROR: unable to get query or query language from select statement" << endl;
1047 return 1;
1048 }
1049
1050
1051 lucier 1.8 char text[1024];
1052 char* _text;
1053
1054 // setup Test Instances
1055 Array<CIMInstance> _instances;
1056
1057 if (!populateInstances(_instances, className, _ns, _rep))
1058 return 1;
1059
1060 // demo setup
1061 if(argc == 3 && strcmp(argv[2],"Demo") == 0){
1062 cout << "Running Demo..." << endl;
1063 _instances.clear();
1064 const CIMName _testclassDEMO(String("CIM_Process"));
|
1065 kumpf 1.31 _instances.appendArray(_rep->enumerateInstancesForSubtree( _ns, _testclassDEMO ));
|
1066 lucier 1.8 _instances.remove(6,6);
1067 }
1068
1069 for(Uint32 i = 0; i < _instances.size(); i++){
1070 CIMObjectPath op = _instances[i].getPath();
|
1071 lucier 1.12 op.setHost("a.b.com");
1072 op.setNameSpace(_ns);
|
1073 lucier 1.8 _instances[i].setPath(op);
1074 }
1075 // setup input stream
1076 if(argc >= 2){
1077 ifstream queryInputSource(argv[1]);
1078 if(!queryInputSource){
1079 cout << "Cannot open input file.\n" << endl;
1080 return 1;
1081 }
1082 int statementsInError = 0;
|
1083 chuck 1.14 int lineNum = 0;
1084 while(!queryInputSource.eof())
1085 {
1086 lineNum++;
|
1087 lucier 1.8 queryInputSource.getline(text, 1024);
1088 char* _ptr = text;
1089 _text = strcat(_ptr,"\n");
1090 // check for comments and ignore
1091 // a comment starts with a # as the first non whitespace character on the line
1092 char _comment = '#';
1093 int i = 0;
1094 while(text[i] == ' ' || text[i] == '\t') i++; // ignore whitespace
1095 if(text[i] != _comment)
|
1096 chuck 1.14 {
1097 if(!(strlen(_text) < 2) && i == 0)
1098 {
|
1099 lucier 1.8 try {
1100 CQLParser::parse(text,_ss);
1101 _statements.append(_ss);
1102 } // end-try
1103 catch(Exception& e){
|
1104 humberto 1.15 cout << "Caught Exception: " << getStatementString(e.getMessage()) << endl;
|
1105 chuck 1.23 try
1106 {
|
1107 chuck 1.24 String stmt(text);
1108 cout << "Statement with error = " << getStatementString(stmt) << endl;
|
1109 chuck 1.23 }
|
1110 chuck 1.24 catch (Exception & e1)
|
1111 chuck 1.23 {
1112 cout << "Error printing statement: " << getStatementString(e1.getMessage()) << endl;
1113 }
|
1114 chuck 1.24
|
1115 lucier 1.8 _ss.clear();
1116 statementsInError++;
1117 } // end-catch
1118 } // end-if
|
1119 chuck 1.14 else
1120 {
1121 if (cqlcli_verbose)
1122 cout << "IGNORING line " << lineNum << endl;
1123 }
1124 }
|
1125 humberto 1.16 // while !eof behaves differently on HP-UX, seems like it takes an extra iteration to hit eof, this leaves "text" with
1126 // the previous value from getline(..), which causes a duplicate parse of the last select statement in the query file,
1127 // FIX: we clear text before doing another getline(..)
1128 text[0] = 0;
|
1129 lucier 1.8 } // end-while
1130 queryInputSource.close();
1131 if (statementsInError)
1132 {
1133 cout << "There were " << statementsInError << " statements that did NOT parse." << endl;
1134 // return 1;
1135 }
1136 try{
1137 _applyProjection(_statements,_instances, testOption);
1138 _validateProperties(_statements,_instances, testOption);
1139 _getPropertyList(_statements,_instances, _ns, testOption);
1140 _evaluate(_statements,_instances, testOption);
1141 _normalize(_statements,_instances, testOption);
1142 }
1143 catch(Exception e){
|
1144 humberto 1.15 cout << getStatementString(e.getMessage()) << endl;
|
1145 lucier 1.8 }
1146 catch(...){
1147 cout << "CAUGHT ... BADNESS HAPPENED!!!" << endl;
1148 }
1149 }else{
1150 cout << "Invalid number of arguments.\n" << endl;
1151 }
|
1152 humberto 1.18 delete _rep; // cleanup repository pointer
1153 }// necessary when testing with Purifty so that _statements goes out of scope before the program exits
|
1154 lucier 1.8 return 0;
|
1155 chuck 1.2 }
1156
|