1 mike 1.1 /*
2 **==============================================================================
3 **
4 ** Open Management Infrastructure (OMI)
5 **
6 ** Copyright (c) Microsoft Corporation
7 **
8 ** Licensed under the Apache License, Version 2.0 (the "License"); you may not
9 ** use this file except in compliance with the License. You may obtain a copy
10 ** of the License at
11 **
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 **
14 ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 ** MERCHANTABLITY OR NON-INFRINGEMENT.
18 **
19 ** See the Apache 2 License for the specific language governing permissions
20 ** and limitations under the License.
21 **
22 mike 1.1 **==============================================================================
23 */
24
25 #include <string>
26 #include <vector>
27 #include <iostream>
28 #include <ut/ut.h>
29 #include <base/lib.h>
30 #include <base/paths.h>
31 #include <base/base.h>
32
33 #if MI_CHAR_TYPE == 1
34 typedef std::string String;
35 #else
36 typedef std::wstring String;
37 #endif
38
39 static inline void* LoadLib(const char* file)
40 {
41 char path[MAX_PATH_SIZE];
42 Lib_Format(path, GetPath(ID_LIBDIR), file);
43 mike 1.1 void* lib = Lib_Open(path);
44
45 if (lib)
46 return lib;
47
48 /* try just name - needed by build team, since they have different output folders */
49 return Lib_Open(file);
50 }
51
52 using namespace std;
53
54 //==============================================================================
55 //
56 // Context
57 //
58 //==============================================================================
59
60 #define CONTEXT_MAGIC 0X82D183A8
61
62 class Context : public MI_Context
63 {
64 mike 1.1 public:
65
66 Context()
67 {
68 // Set magic number.
69 magic = CONTEXT_MAGIC;
70
71 Batch_Init(&batch, 64);
72
73 // Initialize function table.
74 memset(&_ft, 0, sizeof(_ft));
75 _ft.PostResult = Context::_PostResult;
76 _ft.ConstructInstance = Context::_ConstructInstance;
77 _ft.ConstructParameters = Context::_ConstructParameters;
78 _ft.PostInstance = Context::_PostInstance;
79 ft = &_ft;
80 }
81
82 ~Context()
83 {
84 magic = 0;
85 mike 1.1 clearResults();
86
87 Batch_Destroy(&batch);
88 }
89
90 Batch batch;
91 MI_Result result;
92 vector<MI_Instance*> instances;
93
94 void clearResults()
95 {
96 result = MI_RESULT_OK;
97
98 for (size_t i = 0; i < instances.size(); i++)
99 {
100 MI_Result r = __MI_Instance_Delete(instances[i]);
101 UT_ASSERT(r == MI_RESULT_OK);
102 }
103
104 instances.clear();
105 }
106 mike 1.1
107 private:
108
109 MI_ContextFT _ft;
110
111 static MI_Result MI_CALL _PostResult(
112 MI_Context* context,
113 MI_Result result)
114 {
115 Context* ctx = (Context*)context;
116 UT_ASSERT(ctx->magic == CONTEXT_MAGIC);
117
118 ctx->result = result;
119 return MI_RESULT_OK;
120 }
121
122 static MI_Result MI_CALL _ConstructInstance(
123 MI_Context* context,
124 const MI_ClassDecl* classDecl,
125 MI_Instance* instance)
126 {
127 mike 1.1 Context* ctx = (Context*)context;
128
129 UT_ASSERT(ctx->magic == CONTEXT_MAGIC);
130
131 MI_Result r = Instance_Construct(instance, classDecl, &ctx->batch);
132
133 if (r != MI_RESULT_OK)
134 return MI_RESULT_FAILED;
135
136 return MI_RESULT_OK;
137 }
138
139 static MI_Result MI_CALL _ConstructParameters(
140 MI_Context* context,
141 const MI_MethodDecl* methodDecl,
142 MI_Instance* instance)
143 {
144 Context* ctx = (Context*)context;
145 UT_ASSERT(ctx->magic == CONTEXT_MAGIC);
146
147 MI_Result r = Parameters_Init(instance, methodDecl, &ctx->batch);
148 mike 1.1
149 if (r != MI_RESULT_OK)
150 return MI_RESULT_FAILED;
151
152 return MI_RESULT_OK;
153 }
154
155 static MI_Result MI_CALL _PostInstance(
156 MI_Context* context,
157 const MI_Instance* instance)
158 {
159 Context* ctx = (Context*)context;
160 UT_ASSERT(ctx->magic == CONTEXT_MAGIC);
161
162 ctx->result = MI_RESULT_OK;
163
164 UT_ASSERT(instance != 0);
165
166 MI_Instance* inst = NULL;
167
168 Instance_Clone(instance, &inst, &ctx->batch);
169 mike 1.1 UT_ASSERT(inst != NULL);
170 ctx->instances.push_back(inst);
171
172 return MI_RESULT_OK;
173 }
174
175 MI_Uint32 magic;
176 };
177
178 //==============================================================================
179 //
180 // Module
181 //
182 //==============================================================================
183
184 //extern "C" MI_EXPORT MI_Module* MI_Main(MI_Context* context);
185 typedef MI_Module* (*PfnMI_Main)(MI_Context* context);
186
187 class ModuleHandle
188 {
189 public:
190 mike 1.1
191 ModuleHandle(Context& context, const MI_Char* className, const char* lib_file) :
192 _context(context),
193 _classDecl(0),
194 _classSelf(0),
195 _className(className)
196 {
197 _lib = LoadLib(lib_file);
198
199 UT_ASSERT( _lib != 0 );
200
201 PfnMI_Main pfn = (PfnMI_Main)Lib_Sym(_lib, "MI_Main" );
202 UT_ASSERT( pfn != 0 );
203
204 // Call MI_Main() to get an instance of the provider.
205 _module = pfn((MI_Context*)&_context);
206 UT_ASSERT(_module != 0);
207 UT_ASSERT(_module->version == MI_VERSION);
208 UT_ASSERT(_module->schemaDecl != 0);
209
210 // Load the provider.
211 mike 1.1 UT_ASSERT(_module->Load);
212 _module->Load(&_moduleSelf, (MI_Context*)&_context);
213 }
214
215 ~ModuleHandle()
216 {
217 _context.clearResults();
218 // Unload the provider.
219 UT_ASSERT(_module != 0);
220 UT_ASSERT(_module->Unload != 0);
221 UT_ASSERT(_context.ft != 0);
222 _module->Unload(_moduleSelf, (MI_Context*)&_context);
223
224 if ( _lib != 0 )
225 Lib_Close(_lib);
226
227 }
228
229 MI_Instance* newClass()
230 {
231 UT_ASSERT(_classDecl != 0);
232 mike 1.1 MI_Instance* inst;
233 MI_Result r = Instance_New(&inst, _classDecl, &_context.batch);
234 UT_ASSERT(r == MI_RESULT_OK);
235 return inst;
236 }
237
238 MI_Instance* newClass(const MI_Char* className)
239 {
240 MI_ClassDecl* cd = SchemaDecl_FindClassDecl(_module->schemaDecl,
241 className);
242 UT_ASSERT(cd != 0);
243 MI_Instance* inst;
244 MI_Result r = Instance_New(&inst, cd, &_context.batch);
245 UT_ASSERT(r == MI_RESULT_OK);
246 return inst;
247 }
248
249 MI_Instance* newParameters(const MI_Char* methodName)
250 {
251 UT_ASSERT(_classDecl != 0);
252 MI_MethodDecl* md = ClassDecl_FindMethodDecl(_classDecl, methodName);
253 mike 1.1 UT_ASSERT(md);
254
255 MI_Instance* result;
256 MI_Result r = Parameters_New(&result, md, &_context.batch);
257 UT_ASSERT(r == MI_RESULT_OK);
258
259 return result;
260 }
261
262 void callLoad()
263 {
264 // Find the class declaration for the given class.
265 _classDecl = SchemaDecl_FindClassDecl(
266 _module->schemaDecl, _className.c_str());
267
268 UT_ASSERT(_classDecl != 0);
269
270 // Call the class initialize function.
271 UT_ASSERT(_classDecl->providerFT);
272 UT_ASSERT(_classDecl->providerFT->Load);
273 _classDecl->providerFT->Load(&_classSelf, _moduleSelf, (MI_Context*)&_context);
274 mike 1.1 }
275
276 void callUnload()
277 {
278 // Unload the class provider.
279 UT_ASSERT(_classDecl->providerFT);
280 UT_ASSERT(_classDecl->providerFT->Unload);
281 _classDecl->providerFT->Unload(_classSelf, (MI_Context*)&_context);
282 _classDecl = 0;
283 }
284
285 void callGet(
286 const MI_Instance* instanceName,
287 const MI_PropertySet* propertySet)
288 {
289 UT_ASSERT(_classDecl);
290 return _classDecl->providerFT->GetInstance(
291 _classSelf,
292 (MI_Context*)&_context,
293 __nameSpace,
294 __className,
295 mike 1.1 instanceName,
296 propertySet);
297 }
298
299 void callInvoke(
300 const MI_Char* methodName,
301 const MI_Instance* instanceName,
302 const MI_Instance* parameters)
303 {
304 UT_ASSERT(instanceName != 0);
305 UT_ASSERT(parameters != 0);
306 UT_ASSERT(_classDecl != 0);
307 MI_MethodDecl* md = ClassDecl_FindMethodDecl(_classDecl,
308 methodName);
309 UT_ASSERT(md);
310
311 return md->function(_classSelf, (MI_Context*)&_context,
312 __nameSpace, __className, __methodName, instanceName, parameters);
313 }
314
315 void callEnumerate()
316 mike 1.1 {
317 UT_ASSERT(_classDecl);
318 return _classDecl->providerFT->EnumerateInstances(
319 _classSelf,
320 (MI_Context*)&_context,
321 __nameSpace,
322 __className,
323 NULL,
324 MI_FALSE,
325 NULL);
326 }
327
328 void callCreate(
329 const MI_Instance* newInstance)
330 {
331 return _classDecl->providerFT->CreateInstance(
332 _classSelf,
333 (MI_Context*)&_context,
334 __nameSpace,
335 __className,
336 newInstance);
337 mike 1.1 }
338
339 void callModify(
340 const MI_Instance* modifiedInstance,
341 const MI_PropertySet* propertySet)
342 {
343 UT_ASSERT(_classDecl);
344 return _classDecl->providerFT->ModifyInstance(
345 _classSelf,
346 (MI_Context*)&_context,
347 __nameSpace,
348 __className,
349 modifiedInstance,
350 propertySet);
351 }
352
353 void callDelete(
354 const MI_Instance* instanceName)
355 {
356 UT_ASSERT(_classDecl);
357 return _classDecl->providerFT->DeleteInstance(
358 mike 1.1 _classSelf,
359 (MI_Context*)&_context,
360 __nameSpace,
361 __className,
362 instanceName);
363 }
364
365 void callAssociators(MI_Instance* instanceName)
366 {
367 UT_ASSERT(_classDecl);
368
369 const MI_Char* role1 = 0;
370 const MI_Char* role2 = 0;
371
372 for (MI_Uint32 i = 0; i < _classDecl->numProperties; i++)
373 {
374 const MI_PropertyDecl* pd = _classDecl->properties[i];
375
376 if (pd->type == MI_REFERENCE)
377 {
378 if (!role1)
379 mike 1.1 role1 = pd->name;
380 else if (!role2)
381 role2 = pd->name;
382 }
383 }
384
385 _classDecl->providerFT->AssociatorInstances(
386 _classSelf,
387 (MI_Context*)&_context,
388 __nameSpace,
389 __className,
390 instanceName, /* instanceName */
391 NULL, /* resultClass */
392 role1, /* role */
393 role2, /* resultRole */
394 NULL, /* propertySet */
395 MI_FALSE, /* keysOnly */
396 NULL); /* filter */
397
398 _classDecl->providerFT->AssociatorInstances(
399 _classSelf,
400 mike 1.1 (MI_Context*)&_context,
401 __nameSpace,
402 __className,
403 instanceName, /* instanceName */
404 NULL, /* resultClass */
405 role2, /* role */
406 role1, /* resultRole */
407 NULL, /* propertySet */
408 MI_FALSE, /* keysOnly */
409 NULL); /* filter */
410 }
411
412 void callReferences(MI_Instance* instanceName)
413 {
414 UT_ASSERT(_classDecl);
415
416 const MI_Char* role1 = 0;
417 const MI_Char* role2 = 0;
418
419 for (MI_Uint32 i = 0; i < _classDecl->numProperties; i++)
420 {
421 mike 1.1 const MI_PropertyDecl* pd = _classDecl->properties[i];
422
423 if (pd->type == MI_REFERENCE)
424 {
425 if (!role1)
426 role1 = pd->name;
427 else if (!role2)
428 role2 = pd->name;
429 }
430 }
431
432 _classDecl->providerFT->ReferenceInstances(
433 _classSelf,
434 (MI_Context*)&_context,
435 __nameSpace,
436 __className,
437 instanceName, /* instanceName */
438 role1, /* role */
439 NULL, /* propertySet */
440 MI_FALSE, /* keysOnly */
441 NULL); /* filter */
442 mike 1.1
443 _classDecl->providerFT->ReferenceInstances(
444 _classSelf,
445 (MI_Context*)&_context,
446 __nameSpace,
447 __className,
448 instanceName, /* instanceName */
449 role2, /* role */
450 NULL, /* propertySet */
451 MI_FALSE, /* keysOnly */
452 NULL); /* filter */
453 }
454
455 MI_ClassDecl* getClassDecl()
456 {
457 return _classDecl;
458 }
459
460 private:
461
462 ModuleHandle();
463 mike 1.1
464 ModuleHandle& operator=(const ModuleHandle&);
465
466 Context& _context;
467
468 // Module and self.
469 MI_Module* _module;
470 MI_Module_Self* _moduleSelf;
471
472 // Person class and self.
473 MI_ClassDecl* _classDecl;
474 void* _classSelf;
475
476 String _className;
477 void* _lib;
478 };
479
480 //==============================================================================
481 //
482 // Test functions
483 //
484 mike 1.1 //==============================================================================
485
486 static void setUp()
487 {
488 }
489
490 static void cleanup()
491 {
492 }
493
494 static void ExpectNotFound(
495 Context& ctx,
496 ModuleHandle& mh,
497 MI_Uint32 key)
498 {
499 MI_Result r;
500
501 // Prepare instanceName
502 MI_Instance* instanceName = mh.newClass();
503 {
504 MI_Value value;
505 mike 1.1 value.uint32 = key;
506 r = __MI_Instance_SetElement(instanceName, MI_T("Key"), &value, MI_UINT32, 0);
507 UT_ASSERT(r == MI_RESULT_OK);
508 }
509
510 // Call the provider's Get method.
511 mh.callGet((MI_Instance*)instanceName, NULL);
512
513 // Check the result.
514 UT_ASSERT(ctx.result == MI_RESULT_NOT_FOUND);
515 UT_ASSERT(ctx.instances.size() == 0);
516 ctx.instances.clear();
517
518 __MI_Instance_Delete(instanceName);
519 }
520
521 static void GetPerson(
522 Context& ctx,
523 ModuleHandle& mh,
524 MI_Uint32 key,
525 const MI_Char* first,
526 mike 1.1 const MI_Char* last)
527 {
528 MI_Result r;
529
530 // Prepare instanceName
531 MI_Instance* instanceName = mh.newClass();
532 {
533 MI_Value value;
534 value.uint32 = key;
535 r = __MI_Instance_SetElement(instanceName, MI_T("Key"), &value, MI_UINT32, 0);
536 UT_ASSERT(r == MI_RESULT_OK);
537 }
538
539 // Call the provider's Get method.
540 mh.callGet((MI_Instance*)instanceName, NULL);
541 __MI_Instance_Delete(instanceName); instanceName = 0;
542
543 // Check the result.
544 UT_ASSERT(ctx.result == MI_RESULT_OK);
545 UT_ASSERT(ctx.instances.size() == 1);
546
547 mike 1.1 MI_Instance* inst = ctx.instances[0];
548 ctx.instances.clear();
549
550 // Check MSFT_Person.Key
551 {
552 MI_Uint32 flags;
553 MI_Value value;
554 MI_Type type;
555 r = __MI_Instance_GetElement(inst, MI_T("Key"), &value, &type, &flags, 0);
556 UT_ASSERT(r == MI_RESULT_OK);
557 UT_ASSERT(type == MI_UINT32);
558 UT_ASSERT(!(flags & MI_FLAG_NULL));
559 UT_ASSERT(value.uint32 == key);
560 }
561
562 // Check MSFT_Person.First
563 {
564 MI_Uint32 flags;
565 MI_Value value;
566 MI_Type type;
567 r = __MI_Instance_GetElement(inst, MI_T("First"), &value, &type, &flags, 0);
568 mike 1.1 UT_ASSERT(r == MI_RESULT_OK);
569 UT_ASSERT(type == MI_STRING);
570 UT_ASSERT(!(flags & MI_FLAG_NULL));
571 UT_ASSERT(value.string != NULL);
572 UT_ASSERT(value.string == String(first));
573 }
574
575 // Check MSFT_Person.Last
576 {
577 MI_Uint32 flags;
578 MI_Value value;
579 MI_Type type;
580 r = __MI_Instance_GetElement(inst, MI_T("Last"), &value, &type, &flags, 0);
581 UT_ASSERT(r == MI_RESULT_OK);
582 UT_ASSERT(type == MI_STRING);
583 UT_ASSERT(!(flags & MI_FLAG_NULL));
584 UT_ASSERT(value.string != NULL);
585 UT_ASSERT(value.string == String(last));
586 }
587
588 __MI_Instance_Delete(inst);
589 mike 1.1 }
590
591 static void EnumeratePerson(
592 Context& ctx,
593 ModuleHandle& mh)
594 {
595 MI_Result r;
596
597 // Call the provider's enumeate method.
598 mh.callEnumerate();
599
600 // Check the result.
601 UT_ASSERT(ctx.result == MI_RESULT_OK);
602 UT_ASSERT(ctx.instances.size() == 2);
603
604 MI_Instance* inst0 = ctx.instances[0];
605 MI_Instance* inst1 = ctx.instances[1];
606 ctx.instances.clear();
607
608 #if 0
609 __MI_Instance_Print(stdout, inst0);
610 mike 1.1 #endif
611
612 // Check inst0:
613 {
614 MI_Uint32 flags;
615 MI_Value value;
616 MI_Type type;
617 r = __MI_Instance_GetElement(inst0, MI_T("Key"), &value, &type, &flags, 0);
618 UT_ASSERT(r == MI_RESULT_OK);
619 UT_ASSERT(type == MI_UINT32);
620 UT_ASSERT(!(flags & MI_FLAG_NULL));
621 UT_ASSERT(value.uint32 == 1);
622 }
623 {
624 MI_Uint32 flags;
625 MI_Value value;
626 MI_Type type;
627 r = __MI_Instance_GetElement(inst0, MI_T("First"), &value, &type, &flags, 0);
628 UT_ASSERT(r == MI_RESULT_OK);
629 UT_ASSERT(type == MI_STRING);
630 UT_ASSERT(!(flags & MI_FLAG_NULL));
631 mike 1.1 UT_ASSERT(value.string != NULL);
632 UT_ASSERT(value.string == String(MI_T("George")));
633 }
634 {
635 MI_Uint32 flags;
636 MI_Value value;
637 MI_Type type;
638 r = __MI_Instance_GetElement(inst0, MI_T("Last"), &value, &type, &flags, 0);
639 UT_ASSERT(r == MI_RESULT_OK);
640 UT_ASSERT(type == MI_STRING);
641 UT_ASSERT(!(flags & MI_FLAG_NULL));
642 UT_ASSERT(value.string != NULL);
643 UT_ASSERT(value.string == String(MI_T("Washington")));
644 }
645
646 __MI_Instance_Delete(inst0);
647
648 // Check inst1:
649 {
650 MI_Uint32 flags;
651 MI_Value value;
652 mike 1.1 MI_Type type;
653 r = __MI_Instance_GetElement(inst1, MI_T("Key"), &value, &type, &flags, 0);
654 UT_ASSERT(r == MI_RESULT_OK);
655 UT_ASSERT(type == MI_UINT32);
656 UT_ASSERT(!(flags & MI_FLAG_NULL));
657 UT_ASSERT(value.uint32 == 2);
658 }
659 {
660 MI_Uint32 flags;
661 MI_Value value;
662 MI_Type type;
663 r = __MI_Instance_GetElement(inst1, MI_T("First"), &value, &type, &flags, 0);
664 UT_ASSERT(r == MI_RESULT_OK);
665 UT_ASSERT(type == MI_STRING);
666 UT_ASSERT(!(flags & MI_FLAG_NULL));
667 UT_ASSERT(value.string != NULL);
668 UT_ASSERT(value.string == String(MI_T("John")));
669 }
670 {
671 MI_Uint32 flags;
672 MI_Value value;
673 mike 1.1 MI_Type type;
674 r = __MI_Instance_GetElement(inst1, MI_T("Last"), &value, &type, &flags, 0);
675 UT_ASSERT(r == MI_RESULT_OK);
676 UT_ASSERT(type == MI_STRING);
677 UT_ASSERT(!(flags & MI_FLAG_NULL));
678 UT_ASSERT(value.string != NULL);
679 UT_ASSERT(value.string == String(MI_T("Adams")));
680 }
681
682 __MI_Instance_Delete(inst1);
683 }
684
685 static void CreatePerson(
686 Context& ctx,
687 ModuleHandle& mh,
688 MI_Uint32 key,
689 const MI_Char* first,
690 const MI_Char* last)
691 {
692 MI_Result r;
693
694 mike 1.1 // Prepare the newInstance argument.
695 MI_Instance* newInstance = mh.newClass();
696 {
697 MI_Value value;
698 value.uint32 = key;
699
700 // MSFT_Person.Key:
701 r = __MI_Instance_SetElement(newInstance, MI_T("Key"), &value, MI_UINT32, 0);
702 UT_ASSERT(r == MI_RESULT_OK);
703
704 // MSFT_Person.First:
705 value.string = (MI_Char*)first;
706 r = __MI_Instance_SetElement(newInstance, MI_T("First"), &value, MI_STRING, 0);
707 UT_ASSERT(r == MI_RESULT_OK);
708
709 // MSFT_Person.Last:
710 value.string = (MI_Char*)last;
711 r = __MI_Instance_SetElement(newInstance, MI_T("Last"), &value, MI_STRING, 0);
712 UT_ASSERT(r == MI_RESULT_OK);
713 }
714
715 mike 1.1 // Call the provider's Create method.
716 mh.callCreate((MI_Instance*)newInstance);
717 UT_ASSERT(ctx.result == MI_RESULT_OK);
718 UT_ASSERT(ctx.instances.size() == 1);
719
720 ctx.clearResults();
721
722 // Call the provider's Create method.
723 mh.callModify((MI_Instance*)newInstance, NULL);
724 __MI_Instance_Delete(newInstance); newInstance = 0;
725 UT_ASSERT(ctx.result == MI_RESULT_NOT_SUPPORTED);
726 UT_ASSERT(ctx.instances.size() == 0);
727 }
728
729 static void DeletePerson(
730 Context& ctx,
731 ModuleHandle& mh,
732 MI_Uint32 key)
733 {
734 MI_Result r;
735
736 mike 1.1 // Prepare instanceName
737 MI_Instance* instanceName = mh.newClass();
738 {
739 MI_Value value;
740 value.uint32 = key;
741 r = __MI_Instance_SetElement(instanceName, MI_T("Key"), &value, MI_UINT32, 0);
742 UT_ASSERT(r == MI_RESULT_OK);
743 }
744
745 // Call the provider's Delete method.
746 mh.callDelete((MI_Instance*)instanceName);
747 __MI_Instance_Delete(instanceName); instanceName = 0;
748
749 // Check the result.
750 UT_ASSERT(ctx.result == MI_RESULT_OK);
751 }
752
753 static void InvokePersonAdd(
754 Context& ctx,
755 ModuleHandle& mh)
756 {
757 mike 1.1 // Prepare instanceName
758 MI_Instance* instanceName = mh.newClass();
759 Instance_SetUint32(instanceName, MI_T("Key"), 1);
760 {
761 MI_Result r;
762 MI_Instance* params = mh.newParameters(MI_T("Add"));
763 UT_ASSERT(params);
764
765 Instance_SetReal32(params, MI_T("X"), 100);
766 Instance_SetReal32(params, MI_T("Y"), 200);
767
768 #if 0
769 __MI_Instance_Print(stdout, params);
770 #endif
771
772 mh.callInvoke(MI_T("Add"), instanceName, params);
773 __MI_Instance_Delete(instanceName); instanceName = 0;
774 __MI_Instance_Delete(params); params = 0;
775
776 UT_ASSERT(ctx.result == MI_RESULT_OK);
777 UT_ASSERT(ctx.instances.size() == 1);
778 mike 1.1 MI_Instance* out = ctx.instances[0];
779 UT_ASSERT(out != 0);
780 ctx.instances.clear();
781
782 MI_Real32 z;
783 r = Instance_GetReal32(out, MI_T("Z"), &z);
784 UT_ASSERT(r == MI_RESULT_OK);
785 UT_ASSERT(z == 300.0);
786
787 #if 0
788 __MI_Instance_Print(stdout, out);
789 #endif
790 __MI_Instance_Delete(out);
791 }
792
793 }
794
795 template<typename T, typename C_ARRAY_T, MI_Type type>
796 static void TestArray(const MI_Char* prop_name, const vector< T >& in_array, MI_Instance* param)
797 {
798 C_ARRAY_T value;
799 mike 1.1
800 T sum = 0;
801 for ( size_t i = 0; i < in_array.size(); i++ )
802 sum += in_array[i];
803
804 UT_ASSERT(MI_RESULT_OK == Instance_GetValue(param,prop_name,&value,type));
805 UT_ASSERT(value.size == 2);
806 UT_ASSERT(value.data[0] == (T)in_array.size());
807 UT_ASSERT(value.data[1] == sum);
808 }
809
810
811 static void InvokeTestAllTypes(
812 Context& ctx,
813 ModuleHandle& mh)
814 {
815 // Prepare instanceName
816 MI_Instance* instanceName = mh.newClass();
817 Instance_SetUint32(instanceName, MI_T("Key"), 1);
818 {
819 MI_Instance* params = mh.newParameters(MI_T("TestAllTypes"));
820 mike 1.1 UT_ASSERT(params);
821
822 UT_ASSERT(MI_RESULT_OK == Instance_SetBoolean(params, MI_T("b"), MI_TRUE));
823 UT_ASSERT(MI_RESULT_OK == Instance_SetUint8(params, MI_T("u8"), 8));
824 UT_ASSERT(MI_RESULT_OK == Instance_SetSint8(params, MI_T("s8"), -8));
825 UT_ASSERT(MI_RESULT_OK == Instance_SetUint16(params, MI_T("u16"), 16));
826 UT_ASSERT(MI_RESULT_OK == Instance_SetSint16(params, MI_T("s16"), -16));
827 UT_ASSERT(MI_RESULT_OK == Instance_SetUint32(params, MI_T("u32"), 32));
828 UT_ASSERT(MI_RESULT_OK == Instance_SetSint32(params, MI_T("s32"), -32));
829 UT_ASSERT(MI_RESULT_OK == Instance_SetUint64(params, MI_T("u64"), 64));
830 UT_ASSERT(MI_RESULT_OK == Instance_SetSint64(params, MI_T("s64"), -64));
831 UT_ASSERT(MI_RESULT_OK == Instance_SetReal32(params, MI_T("r32"), 32.32f));
832 UT_ASSERT(MI_RESULT_OK == Instance_SetReal64(params, MI_T("r64"), 64.64));
833 MI_Datetime dt;
834 dt.isTimestamp = 1;
835 dt.u.timestamp.year = 1;
836 dt.u.timestamp.month = 2;
837 dt.u.timestamp.day = 3;
838 dt.u.timestamp.hour = 4;
839 dt.u.timestamp.minute = 5;
840 dt.u.timestamp.second = 6;
841 mike 1.1 dt.u.timestamp.microseconds = 7;
842 dt.u.timestamp.utc = 8;
843
844 UT_ASSERT(MI_RESULT_OK == Instance_SetDatetime(params, MI_T("dt"), &dt));
845 UT_ASSERT(MI_RESULT_OK == Instance_SetString(params, MI_T("s"), MI_T("input string")));
846 UT_ASSERT(MI_RESULT_OK == Instance_SetChar16(params, MI_T("c16"), 1616));
847
848 // reference
849 MI_Instance* new_ref = mh.newClass();
850 MI_Value value;
851 value.reference = new_ref;
852 UT_ASSERT(MI_RESULT_OK == Instance_SetUint32(value.reference, MI_T("Key"), 19));
853 UT_ASSERT(MI_RESULT_OK == __MI_Instance_SetElement(params, MI_T("rf"), &value, MI_REFERENCE, 0));
854
855 // arrays of types
856 MI_Boolean ba[] = {MI_FALSE};
857 value.booleana.data = ba;
858 value.booleana.size = MI_COUNT(ba);
859 UT_ASSERT(MI_RESULT_OK == __MI_Instance_SetElement(params, MI_T("ba"), &value, MI_BOOLEANA, 0));
860
861 #define DECLARE_ARRAY_SET_PROP(a_type,a_name,a_size,a_value_field,a_var_str_name,a_enum_type) \
862 mike 1.1 vector<a_type> a_name; \
863 { int count = a_size; while( count-- > 0 ) {a_name.push_back( (a_type)rand());} }\
864 /* several special values */ \
865 a_name.push_back(0); a_name.push_back((a_type)-1); a_name.push_back( (a_type)((MI_Uint64(1)<<(sizeof(a_type)*8-1))-1) ); \
866 /*MI_Sint8 s8A[] = {-128,0,7,127,4}; */ \
867 value.a_value_field.data = &a_name[0]; \
868 value.a_value_field.size = (MI_Uint32)a_name.size(); \
869 /*value.sint8a.data = s8A; value.sint8a.size = MI_COUNT(s8A); */ \
870 UT_ASSERT(MI_RESULT_OK == __MI_Instance_SetElement(params, a_var_str_name, &value, a_enum_type, 0));
871
872 DECLARE_ARRAY_SET_PROP(MI_Uint8,u8A,554,uint8a,MI_T("u8A"),MI_UINT8A);
873 DECLARE_ARRAY_SET_PROP(MI_Sint8,s8A,4,sint8a,MI_T("s8A"),MI_SINT8A);
874 DECLARE_ARRAY_SET_PROP(MI_Uint16,u16A,4,uint16a,MI_T("u16A"),MI_UINT16A);
875 DECLARE_ARRAY_SET_PROP(MI_Sint16,s16A,4,sint16a,MI_T("s16A"),MI_SINT16A);
876 DECLARE_ARRAY_SET_PROP(MI_Uint32,u32A,4,uint32a,MI_T("u32A"),MI_UINT32A);
877 DECLARE_ARRAY_SET_PROP(MI_Sint32,s32A,4,sint32a,MI_T("s32A"),MI_SINT32A);
878 DECLARE_ARRAY_SET_PROP(MI_Uint64,u64A,4,uint64a,MI_T("u64A"),MI_UINT64A);
879 DECLARE_ARRAY_SET_PROP(MI_Sint64,s64A,40,sint64a,MI_T("s64A"),MI_SINT64A);
880
881 // arrays of types
882 MI_String sa[] = {(MI_Char*)MI_T("in str1"),(MI_Char*)MI_T("in str2") };
883 mike 1.1 value.stringa.data = sa;
884 value.stringa.size = MI_COUNT(sa);
885 UT_ASSERT(MI_RESULT_OK == __MI_Instance_SetElement(params, MI_T("sa"), &value, MI_STRINGA, 0));
886
887 #if 0
888 __MI_Instance_Print(stdout, params);
889 #endif
890
891 mh.callInvoke(MI_T("TestAllTypes"), instanceName, params);
892 __MI_Instance_Delete(instanceName); instanceName = 0;
893 __MI_Instance_Delete(params); params = 0;
894 __MI_Instance_Delete(new_ref); new_ref = 0;
895
896 UT_ASSERT(ctx.result == MI_RESULT_OK);
897 UT_ASSERT(ctx.instances.size() == 1);
898 MI_Instance* out = ctx.instances[0];
899 UT_ASSERT(out != 0);
900 ctx.instances.clear();
901
902 // verify output
903 MI_Boolean b;
904 mike 1.1 UT_ASSERT(MI_RESULT_OK == Instance_GetBoolean(out, MI_T("b"), &b));
905 UT_ASSERT( b == MI_FALSE );
906
907 MI_Uint8 u8;
908 UT_ASSERT(MI_RESULT_OK == Instance_GetUint8(out, MI_T("u8"), &u8));
909 UT_ASSERT( u8 == 9 );
910
911 MI_Sint8 s8;
912 UT_ASSERT(MI_RESULT_OK == Instance_GetSint8(out, MI_T("s8"), &s8));
913 UT_ASSERT( s8 == -7 );
914
915 MI_Uint16 u16;
916 UT_ASSERT(MI_RESULT_OK == Instance_GetUint16(out, MI_T("u16"), &u16));
917 UT_ASSERT( u16 == 17 );
918
919 MI_Sint16 s16;
920 UT_ASSERT(MI_RESULT_OK == Instance_GetSint16(out, MI_T("s16"), &s16));
921 UT_ASSERT( s16 == -15 );
922
923 MI_Uint32 u32;
924 UT_ASSERT(MI_RESULT_OK == Instance_GetUint32(out, MI_T("u32"), &u32));
925 mike 1.1 UT_ASSERT( u32 == 33 );
926
927 MI_Sint32 s32;
928 UT_ASSERT(MI_RESULT_OK == Instance_GetSint32(out, MI_T("s32"), &s32));
929 UT_ASSERT( s32 == -31 );
930
931 MI_Uint64 u64;
932 UT_ASSERT(MI_RESULT_OK == Instance_GetUint64(out, MI_T("u64"), &u64));
933 UT_ASSERT( u64 == 65 );
934
935 MI_Sint64 s64;
936 UT_ASSERT(MI_RESULT_OK == Instance_GetSint64(out, MI_T("s64"), &s64));
937 UT_ASSERT( s64 == -63 );
938
939 MI_Real32 r32;
940 UT_ASSERT(MI_RESULT_OK == Instance_GetReal32(out, MI_T("r32"), &r32));
941 UT_ASSERT(r32 == -32.32f);
942
943 MI_Real64 r64;
944 UT_ASSERT(MI_RESULT_OK == Instance_GetReal64(out, MI_T("r64"), &r64));
945 UT_ASSERT(r64 > -64.65 && r64 < -64.63);
946 mike 1.1
947 UT_ASSERT(MI_RESULT_OK == Instance_GetDatetime(out, MI_T("dt"), &dt));
948 UT_ASSERT(dt.isTimestamp == 1 &&
949 dt.u.timestamp.year == 2 &&
950 dt.u.timestamp.month == 3 &&
951 dt.u.timestamp.day == 4 &&
952 dt.u.timestamp.hour == 5 &&
953 dt.u.timestamp.minute == 6 &&
954 dt.u.timestamp.second == 7 &&
955 dt.u.timestamp.microseconds == 8 &&
956 dt.u.timestamp.utc == 9);
957
958
959 MI_Instance* rf = 0;
960 MI_Uint32 rf_key = 0;
961
962 UT_ASSERT(MI_RESULT_OK == Instance_GetReference(out, MI_T("rf"), &rf));
963 UT_ASSERT( 0 != rf );
964 UT_ASSERT(MI_RESULT_OK == Instance_GetUint32(rf,MI_T("Key"), &rf_key ));
965 UT_ASSERT(rf_key == 20);
966
967 mike 1.1 // string
968 MI_String s = 0;
969 UT_ASSERT(MI_RESULT_OK == Instance_GetString(out,MI_T("s"), &s ));
970 UT_ASSERT(0 == memcmp(s, MI_T("inp!"),5*sizeof(MI_Char)));
971
972
973 // char16
974 MI_Char16 c16;
975 UT_ASSERT(MI_RESULT_OK == Instance_GetChar16(out,MI_T("c16"), &c16 ));
976 UT_ASSERT(1617 == c16);
977
978 // return value
979 UT_ASSERT(MI_RESULT_OK == Instance_GetString(out,MI_T("MIReturn"), &s ));
980 UT_ASSERT(0 == memcmp(s, MI_T("100"),4*sizeof(MI_Char)));
981
982 // arrays
983 MI_BooleanA out_ba;
984 UT_ASSERT(MI_RESULT_OK == Instance_GetValue(out,MI_T("ba"),&out_ba,MI_BOOLEANA));
985 UT_ASSERT(out_ba.size == 2);
986 UT_ASSERT(out_ba.data[0] == 0);
987 UT_ASSERT(out_ba.data[1] == 1);
988 mike 1.1
989 TestArray<MI_Uint8,MI_Uint8A,MI_UINT8A>(MI_T("u8A"),u8A,out);
990 TestArray<MI_Sint8,MI_Sint8A,MI_SINT8A>(MI_T("s8A"),s8A,out);
991 TestArray<MI_Uint16,MI_Uint16A,MI_UINT16A>(MI_T("u16A"),u16A,out);
992 TestArray<MI_Sint16,MI_Sint16A,MI_SINT16A>(MI_T("s16A"),s16A,out);
993 TestArray<MI_Uint32,MI_Uint32A,MI_UINT32A>(MI_T("u32A"),u32A,out);
994 TestArray<MI_Sint32,MI_Sint32A,MI_SINT32A>(MI_T("s32A"),s32A,out);
995 TestArray<MI_Uint64,MI_Uint64A,MI_UINT64A>(MI_T("u64A"),u64A,out);
996 TestArray<MI_Sint64,MI_Sint64A,MI_SINT64A>(MI_T("s64A"),s64A,out);
997
998 // strings
999 MI_StringA out_sa;
1000 UT_ASSERT(MI_RESULT_OK == Instance_GetValue(out,MI_T("sa"),&out_sa,MI_STRINGA));
1001 UT_ASSERT(out_sa.size == 3);
1002 UT_ASSERT(0 == memcmp(out_sa.data[0], MI_T("str1"),5*sizeof(MI_Char)));
1003 UT_ASSERT(0 == memcmp(out_sa.data[1], MI_T("str2"),5*sizeof(MI_Char)));
1004 UT_ASSERT(0 == memcmp(out_sa.data[2], MI_T("*"),2*sizeof(MI_Char)));
1005
1006 #if 0
1007 __MI_Instance_Print(stdout, out);
1008 #endif
1009 mike 1.1 __MI_Instance_Delete(out);
1010 }
1011
1012 }
1013
1014 static void TestCloning()
1015 {
1016 MI_Result r;
1017
1018 // find rtti form person provider
1019 Context ctx;
1020 ModuleHandle mh(ctx, MI_T("MSFT_Person"), "PersonProvider");
1021 mh.callLoad();
1022
1023 MI_ClassDecl* cl = mh.getClassDecl();
1024
1025
1026 // Create a new person.
1027 MI_Instance* inst1;
1028 r = Instance_New(&inst1, cl, &ctx.batch);
1029 UT_ASSERT(r == MI_RESULT_OK);
1030 mike 1.1 UT_ASSERT(inst1 != 0);
1031 {
1032 MI_Value value;
1033 value.uint32 = 1;
1034
1035 // MSFT_Person.Key:
1036 r = __MI_Instance_SetElement(inst1, MI_T("Key"), &value, MI_UINT32, 0);
1037 UT_ASSERT(r == MI_RESULT_OK);
1038
1039 // MSFT_Person.First:
1040 value.string = (MI_Char*)MI_T("George");
1041 r = __MI_Instance_SetElement(inst1, MI_T("First"), &value, MI_STRING, 0);
1042 UT_ASSERT(r == MI_RESULT_OK);
1043
1044 // MSFT_Person.Last:
1045 value.string = (MI_Char*)MI_T("Washington");
1046 r = __MI_Instance_SetElement(inst1, MI_T("Last"), &value, MI_STRING, 0);
1047 UT_ASSERT(r == MI_RESULT_OK);
1048 }
1049
1050 // Check fields.
1051 mike 1.1 {
1052 // Check MSFT_Person.Key
1053 {
1054 MI_Uint32 flags;
1055 MI_Value value;
1056 MI_Type type;
1057 r = __MI_Instance_GetElement(inst1, MI_T("Key"), &value, &type, &flags, 0);
1058 UT_ASSERT(r == MI_RESULT_OK);
1059 UT_ASSERT(type == MI_UINT32);
1060 UT_ASSERT(!(flags & MI_FLAG_NULL));
1061 UT_ASSERT(value.uint32 == 1);
1062 }
1063
1064 // Check MSFT_Person.First
1065 {
1066 MI_Uint32 flags;
1067 MI_Value value;
1068 MI_Type type;
1069 r = __MI_Instance_GetElement(inst1, MI_T("First"), &value, &type, &flags, 0);
1070 UT_ASSERT(r == MI_RESULT_OK);
1071 UT_ASSERT(type == MI_STRING);
1072 mike 1.1 UT_ASSERT(!(flags & MI_FLAG_NULL));
1073 UT_ASSERT(value.string != NULL);
1074 UT_ASSERT(value.string == String(MI_T("George")));
1075 }
1076
1077 // Check MSFT_Person.Last
1078 {
1079 MI_Uint32 flags;
1080 MI_Value value;
1081 MI_Type type;
1082 r = __MI_Instance_GetElement(inst1, MI_T("Last"), &value, &type, &flags, 0);
1083 UT_ASSERT(r == MI_RESULT_OK);
1084 UT_ASSERT(type == MI_STRING);
1085 UT_ASSERT(!(flags & MI_FLAG_NULL));
1086 UT_ASSERT(value.string != NULL);
1087 UT_ASSERT(value.string == String(MI_T("Washington")));
1088 }
1089 }
1090
1091 // Clone the person.
1092 MI_Instance* inst2;
1093 mike 1.1 Instance_Clone(inst1, &inst2, &ctx.batch);
1094 UT_ASSERT(inst2 != NULL);
1095
1096 // Get fields back.
1097 {
1098 // Check MSFT_Person.Key
1099 {
1100 MI_Uint32 flags;
1101 MI_Value value;
1102 MI_Type type;
1103 r = __MI_Instance_GetElement(inst2, MI_T("Key"), &value, &type, &flags, 0);
1104 UT_ASSERT(r == MI_RESULT_OK);
1105 UT_ASSERT(type == MI_UINT32);
1106 UT_ASSERT(!(flags & MI_FLAG_NULL));
1107 UT_ASSERT(value.uint32 == 1);
1108 }
1109
1110 // Check MSFT_Person.First
1111 {
1112 MI_Uint32 flags;
1113 MI_Value value;
1114 mike 1.1 MI_Type type;
1115 r = __MI_Instance_GetElement(inst2, MI_T("First"), &value, &type, &flags, 0);
1116 UT_ASSERT(r == MI_RESULT_OK);
1117 UT_ASSERT(type == MI_STRING);
1118 UT_ASSERT(!(flags & MI_FLAG_NULL));
1119 UT_ASSERT(value.string != NULL);
1120 UT_ASSERT(value.string == String(MI_T("George")));
1121 }
1122
1123 // Check MSFT_Person.Last
1124 {
1125 MI_Uint32 flags;
1126 MI_Value value;
1127 MI_Type type;
1128 r = __MI_Instance_GetElement(inst2, MI_T("Last"), &value, &type, &flags, 0);
1129 UT_ASSERT(r == MI_RESULT_OK);
1130 UT_ASSERT(type == MI_STRING);
1131 UT_ASSERT(!(flags & MI_FLAG_NULL));
1132 UT_ASSERT(value.string != NULL);
1133 UT_ASSERT(value.string == String(MI_T("Washington")));
1134 }
1135 mike 1.1 }
1136
1137 // Release the instances.
1138 __MI_Instance_Delete(inst1);
1139 __MI_Instance_Delete(inst2);
1140 }
1141
1142 static void TestPersonProvider(const char* provider_file)
1143 {
1144 Context ctx;
1145 ModuleHandle mh(ctx, MI_T("MSFT_Person"), provider_file);
1146
1147 mh.callLoad();
1148
1149 // Test create:
1150 ExpectNotFound(ctx, mh, 1);
1151 CreatePerson(ctx, mh, 1, MI_T("George"), MI_T("Washington"));
1152 ExpectNotFound(ctx, mh, 2);
1153 CreatePerson(ctx, mh, 2, MI_T("John"), MI_T("Adams"));
1154
1155 // Test get:
1156 mike 1.1 GetPerson(ctx, mh, 1, MI_T("George"), MI_T("Washington"));
1157 GetPerson(ctx, mh, 2, MI_T("John"), MI_T("Adams"));
1158
1159 // Test enumerate:
1160 EnumeratePerson(ctx, mh);
1161
1162 // Test delete:
1163 DeletePerson(ctx, mh, 1);
1164 ExpectNotFound(ctx, mh, 1);
1165
1166 // Test Person.Add():
1167 InvokePersonAdd(ctx, mh);
1168
1169 mh.callUnload();
1170 }
1171
1172 static void TestPersonProviderAllTypes(const char* provider_file)
1173 {
1174 Context ctx;
1175 ModuleHandle mh(ctx, MI_T("MSFT_Person"), provider_file);
1176
1177 mike 1.1 mh.callLoad();
1178
1179 // Test Person.Add():
1180 InvokeTestAllTypes(ctx, mh);
1181
1182 mh.callUnload();
1183 }
1184
1185
1186 static void TestFriendsProvider(const char* provider_file)
1187 {
1188 Context ctx;
1189 ModuleHandle mh(ctx, MI_T("MSFT_Friends"), provider_file);
1190 MI_Result r;
1191
1192 // Load the 'MSFT_Friends' provider.
1193 mh.callLoad();
1194
1195 // Create an instance of class MSFT_Person.
1196 MI_Instance* person = mh.newClass(MI_T("MSFT_Person"));
1197 UT_ASSERT(person != NULL);
1198 mike 1.1
1199 r = Instance_SetUint32(person, MI_T("Key"), 1);
1200 UT_ASSERT(r == MI_RESULT_OK);
1201
1202 #if 0
1203 __MI_Instance_Print(stdout, person);
1204 #endif
1205
1206 // Find associators of this person.
1207 mh.callAssociators(person);
1208
1209 // Check the result.
1210 UT_ASSERT(ctx.result == MI_RESULT_OK);
1211
1212 // Check that we got back exactly one friend.
1213 UT_ASSERT(ctx.instances.size() == 1);
1214 MI_Instance* inst = ctx.instances[0];
1215 UT_ASSERT(inst != 0);
1216 ctx.instances.clear();
1217
1218 // Print the instance.
1219 mike 1.1 #if 0
1220 __MI_Instance_Print(stdout, inst);
1221 #endif
1222
1223 // Now call references.
1224 mh.callReferences(person);
1225 UT_ASSERT(ctx.result == MI_RESULT_NOT_SUPPORTED);
1226 __MI_Instance_Delete(person); person=0;
1227
1228 // Unload the 'MSFT_Friends' class provider.
1229 mh.callUnload();
1230
1231 // Release the instance.
1232 __MI_Instance_Delete(inst);
1233 }
1234
1235 static void TestPersonProvider_C()
1236 {
1237 TestPersonProvider("PersonProvider");
1238 }
1239
1240 mike 1.1 static void TestPersonProviderAllTypes_C()
1241 {
1242 TestPersonProviderAllTypes("PersonProvider");
1243 }
1244
1245 static void TestFriendsProvider_C()
1246 {
1247 TestFriendsProvider("PersonProvider");
1248 }
1249
1250 static void TestPersonProvider_CXX()
1251 {
1252 TestPersonProvider("PersonProviderCXX");
1253 }
1254
1255 static void TestPersonProviderAllTypes_CXX()
1256 {
1257 TestPersonProviderAllTypes("PersonProviderCXX");
1258 }
1259
1260 static void TestFriendsProvider_CXX()
1261 mike 1.1 {
1262 TestFriendsProvider("PersonProviderCXX");
1263 }
1264
1265 static void AllProviderTests()
1266 {
1267 UT_TEST(TestCloning);
1268 UT_TEST(TestPersonProvider_C);
1269 UT_TEST(TestPersonProviderAllTypes_C);
1270 UT_TEST(TestFriendsProvider_C);
1271 UT_TEST(TestPersonProvider_CXX);
1272 UT_TEST(TestFriendsProvider_CXX);
1273 UT_TEST(TestPersonProviderAllTypes_CXX);
1274 }
1275
1276 UT_ENTRY_POINT(AllProviderTests);
|