1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4 
5 using System;
6 using System.Collections.Generic;
7 using System.Linq;
8 using System.Threading;
9 
10 namespace Ice
11 {
12     namespace admin
13     {
14         public class AllTests : global::Test.AllTests
15         {
16             static void
17             testFacets(Ice.Communicator com, bool builtInFacets)
18             {
19                 if(builtInFacets)
20                 {
21                     test(com.findAdminFacet("Properties") != null);
22                     test(com.findAdminFacet("Process") != null);
23                     test(com.findAdminFacet("Logger") != null);
24                     test(com.findAdminFacet("Metrics") != null);
25                 }
26 
27                 Test.TestFacet f1 = new TestFacetI();
28                 Test.TestFacet f2 = new TestFacetI();
29                 Test.TestFacet f3 = new TestFacetI();
30 
31                 com.addAdminFacet(f1, "Facet1");
32                 com.addAdminFacet(f2, "Facet2");
33                 com.addAdminFacet(f3, "Facet3");
34 
35                 test(com.findAdminFacet("Facet1") == f1);
36                 test(com.findAdminFacet("Facet2") == f2);
37                 test(com.findAdminFacet("Facet3") == f3);
38                 test(com.findAdminFacet("Bogus") == null);
39 
40                 Dictionary<string, Ice.Object> facetMap = com.findAllAdminFacets();
41                 if(builtInFacets)
42                 {
43                     test(facetMap.Count == 7);
44                     test(facetMap.ContainsKey("Properties"));
45                     test(facetMap.ContainsKey("Process"));
46                     test(facetMap.ContainsKey("Logger"));
47                     test(facetMap.ContainsKey("Metrics"));
48                 }
49                 else
50                 {
51                     test(facetMap.Count >= 3);
52                 }
53                 test(facetMap.ContainsKey("Facet1"));
54                 test(facetMap.ContainsKey("Facet2"));
55                 test(facetMap.ContainsKey("Facet3"));
56 
57                 try
58                 {
59                     com.addAdminFacet(f1, "Facet1");
60                     test(false);
61                 }
62                 catch(Ice.AlreadyRegisteredException)
63                 {
64                     // Expected
65                 }
66 
67                 try
68                 {
69                     com.removeAdminFacet("Bogus");
70                     test(false);
71                 }
72                 catch(Ice.NotRegisteredException)
73                 {
74                     // Expected
75                 }
76 
77                 com.removeAdminFacet("Facet1");
78                 com.removeAdminFacet("Facet2");
79                 com.removeAdminFacet("Facet3");
80 
81                 try
82                 {
83                     com.removeAdminFacet("Facet1");
84                     test(false);
85                 }
86                 catch(Ice.NotRegisteredException)
87                 {
88                     // Expected
89                 }
90             }
91 
92             public static void allTests(global::Test.TestHelper helper)
93             {
94                 Ice.Communicator communicator = helper.communicator();
95                 var output = helper.getWriter();
96                 output.Write("testing communicator operations... ");
97                 output.Flush();
98                 {
99                     //
100                     // Test: Exercise addAdminFacet, findAdminFacet, removeAdminFacet with a typical configuration.
101                     //
102                     Ice.InitializationData init = new Ice.InitializationData();
103                     init.properties = Ice.Util.createProperties();
104                     init.properties.setProperty("Ice.Admin.Endpoints", "tcp -h 127.0.0.1");
105                     init.properties.setProperty("Ice.Admin.InstanceName", "Test");
106                     Ice.Communicator com = Ice.Util.initialize(init);
107                     testFacets(com, true);
108                     com.destroy();
109                 }
110                 {
111                     //
112                     // Test: Verify that the operations work correctly in the presence of facet filters.
113                     //
114                     Ice.InitializationData init = new Ice.InitializationData();
115                     init.properties = Ice.Util.createProperties();
116                     init.properties.setProperty("Ice.Admin.Endpoints", "tcp -h 127.0.0.1");
117                     init.properties.setProperty("Ice.Admin.InstanceName", "Test");
118                     init.properties.setProperty("Ice.Admin.Facets", "Properties");
119                     Ice.Communicator com = Ice.Util.initialize(init);
120                     testFacets(com, false);
121                     com.destroy();
122                 }
123                 {
124                     //
125                     // Test: Verify that the operations work correctly with the Admin object disabled.
126                     //
127                     Ice.Communicator com = Ice.Util.initialize();
128                     testFacets(com, false);
129                     com.destroy();
130                 }
131                 {
132                     //
133                     // Test: Verify that the operations work correctly with Ice.Admin.Enabled=1
134                     //
135                     Ice.InitializationData init = new Ice.InitializationData();
136                     init.properties = Ice.Util.createProperties();
137                     init.properties.setProperty("Ice.Admin.Enabled", "1");
138                     Ice.Communicator com = Ice.Util.initialize(init);
139                     test(com.getAdmin() == null);
140                     Ice.Identity id = Ice.Util.stringToIdentity("test-admin");
141                     try
142                     {
143                         com.createAdmin(null, id);
144                         test(false);
145                     }
146                     catch(Ice.InitializationException)
147                     {
148                     }
149 
150                     Ice.ObjectAdapter adapter = com.createObjectAdapter("");
151                     test(com.createAdmin(adapter, id) != null);
152                     test(com.getAdmin() != null);
153 
154                     testFacets(com, true);
155                     com.destroy();
156                 }
157                 {
158                     //
159                     // Test: Verify that the operations work correctly when creation of the Admin object is delayed.
160                     //
161                     Ice.InitializationData init = new Ice.InitializationData();
162                     init.properties = Ice.Util.createProperties();
163                     init.properties.setProperty("Ice.Admin.Endpoints", "tcp -h 127.0.0.1");
164                     init.properties.setProperty("Ice.Admin.InstanceName", "Test");
165                     init.properties.setProperty("Ice.Admin.DelayCreation", "1");
166                     Ice.Communicator com = Ice.Util.initialize(init);
167                     testFacets(com, true);
168                     com.getAdmin();
169                     testFacets(com, true);
170                     com.destroy();
171                 }
172                 output.WriteLine("ok");
173 
174                 string @ref = "factory:" + helper.getTestEndpoint(0) + " -t 10000";
175                 Test.RemoteCommunicatorFactoryPrx factory =
176                     Test.RemoteCommunicatorFactoryPrxHelper.uncheckedCast(communicator.stringToProxy(@ref));
177 
178                 output.Write("testing process facet... ");
179                 output.Flush();
180                 {
181                     //
182                     // Test: Verify that Process::shutdown() operation shuts down the communicator.
183                     //
184                     Dictionary<string, string> props = new Dictionary<string, string>();
185                     props.Add("Ice.Admin.Endpoints", "tcp -h 127.0.0.1");
186                     props.Add("Ice.Admin.InstanceName", "Test");
187                     var com = factory.createCommunicator(props);
188                     Ice.ObjectPrx obj = com.getAdmin();
189                     Ice.ProcessPrx proc = Ice.ProcessPrxHelper.checkedCast(obj, "Process");
190                     proc.shutdown();
191                     com.waitForShutdown();
192                     com.destroy();
193                 }
194                 output.WriteLine("ok");
195 
196                 output.Write("testing properties facet... ");
197                 output.Flush();
198                 {
199                     Dictionary<string, string> props = new Dictionary<string, string>();
200                     props.Add("Ice.Admin.Endpoints", "tcp -h 127.0.0.1");
201                     props.Add("Ice.Admin.InstanceName", "Test");
202                     props.Add("Prop1", "1");
203                     props.Add("Prop2", "2");
204                     props.Add("Prop3", "3");
205                     var com = factory.createCommunicator(props);
206                     Ice.ObjectPrx obj = com.getAdmin();
207                     Ice.PropertiesAdminPrx pa = Ice.PropertiesAdminPrxHelper.checkedCast(obj, "Properties");
208 
209                     //
210                     // Test: PropertiesAdmin::getProperty()
211                     //
212                     test(pa.getProperty("Prop2").Equals("2"));
213                     test(pa.getProperty("Bogus").Equals(""));
214 
215                     //
216                     // Test: PropertiesAdmin::getProperties()
217                     //
218                     Dictionary<string, string> pd = pa.getPropertiesForPrefix("");
219                     test(pd.Count == 5);
220                     test(pd["Ice.Admin.Endpoints"].Equals("tcp -h 127.0.0.1"));
221                     test(pd["Ice.Admin.InstanceName"].Equals("Test"));
222                     test(pd["Prop1"].Equals("1"));
223                     test(pd["Prop2"].Equals("2"));
224                     test(pd["Prop3"].Equals("3"));
225 
226                     Dictionary<string, string> changes;
227 
228                     //
229                     // Test: PropertiesAdmin::setProperties()
230                     //
231                     Dictionary<string, string> setProps = new Dictionary<string, string>();
232                     setProps.Add("Prop1", "10"); // Changed
233                     setProps.Add("Prop2", "20"); // Changed
234                     setProps.Add("Prop3", ""); // Removed
235                     setProps.Add("Prop4", "4"); // Added
236                     setProps.Add("Prop5", "5"); // Added
237                     pa.setProperties(setProps);
238                     test(pa.getProperty("Prop1").Equals("10"));
239                     test(pa.getProperty("Prop2").Equals("20"));
240                     test(pa.getProperty("Prop3").Equals(""));
241                     test(pa.getProperty("Prop4").Equals("4"));
242                     test(pa.getProperty("Prop5").Equals("5"));
243                     changes = com.getChanges();
244                     test(changes.Count == 5);
245                     test(changes["Prop1"].Equals("10"));
246                     test(changes["Prop2"].Equals("20"));
247                     test(changes["Prop3"].Equals(""));
248                     test(changes["Prop4"].Equals("4"));
249                     test(changes["Prop5"].Equals("5"));
250                     pa.setProperties(setProps);
251                     changes = com.getChanges();
252                     test(changes.Count == 0);
253 
254                     com.destroy();
255                 }
256                 output.WriteLine("ok");
257 
258                 output.Write("testing logger facet... ");
259                 output.Flush();
260                 {
261                     Dictionary<String, String> props = new Dictionary<String, String>();
262                     props.Add("Ice.Admin.Endpoints", "tcp -h 127.0.0.1");
263                     props.Add("Ice.Admin.InstanceName", "Test");
264                     props.Add("NullLogger", "1");
265                     var com = factory.createCommunicator(props);
266 
267                     com.trace("testCat", "trace");
268                     com.warning("warning");
269                     com.error("error");
270                     com.print("print");
271 
272                     Ice.ObjectPrx obj = com.getAdmin();
273                     Ice.LoggerAdminPrx logger = Ice.LoggerAdminPrxHelper.checkedCast(obj, "Logger");
274                     test(logger != null);
275 
276                     string prefix = null;
277 
278                     //
279                     // Get all
280                     //
281                     Ice.LogMessage[] logMessages = logger.getLog(null, null, -1, out prefix);
282 
283                     test(logMessages.Length == 4);
284                     test(prefix.Equals("NullLogger"));
285                     test(logMessages[0].traceCategory.Equals("testCat") && logMessages[0].message.Equals("trace"));
286                     test(logMessages[1].message.Equals("warning"));
287                     test(logMessages[2].message.Equals("error"));
288                     test(logMessages[3].message.Equals("print"));
289 
290                     //
291                     // Get only errors and warnings
292                     //
293                     com.error("error2");
294                     com.print("print2");
295                     com.trace("testCat", "trace2");
296                     com.warning("warning2");
297 
298                     Ice.LogMessageType[] messageTypes = {
299                                 Ice.LogMessageType.ErrorMessage,
300                                 Ice.LogMessageType.WarningMessage
301                             };
302 
303                     logMessages = logger.getLog(messageTypes, null, -1, out prefix);
304 
305                     test(logMessages.Length == 4);
306                     test(prefix.Equals("NullLogger"));
307 
308                     foreach(var msg in logMessages)
309                     {
310                         test(msg.type == Ice.LogMessageType.ErrorMessage ||
311                              msg.type == Ice.LogMessageType.WarningMessage);
312                     }
313 
314                     //
315                     // Get only errors and traces with Cat = "testCat"
316                     //
317                     com.trace("testCat2", "A");
318                     com.trace("testCat", "trace3");
319                     com.trace("testCat2", "B");
320 
321                     messageTypes = new Ice.LogMessageType[] {
322                                 Ice.LogMessageType.ErrorMessage,
323                                 Ice.LogMessageType.TraceMessage
324                             };
325                     string[] categories = { "testCat" };
326                     logMessages = logger.getLog(messageTypes, categories, -1, out prefix);
327                     test(logMessages.Length == 5);
328                     test(prefix.Equals("NullLogger"));
329 
330                     foreach(var msg in logMessages)
331                     {
332                         test(msg.type == Ice.LogMessageType.ErrorMessage ||
333                             (msg.type == Ice.LogMessageType.TraceMessage && msg.traceCategory.Equals("testCat")));
334                     }
335 
336                     //
337                     // Same, but limited to last 2 messages(trace3 + error3)
338                     //
339                     com.error("error3");
340 
341                     logMessages = logger.getLog(messageTypes, categories, 2, out prefix);
342                     test(logMessages.Length == 2);
343                     test(prefix.Equals("NullLogger"));
344 
345                     test(logMessages[0].message.Equals("trace3"));
346                     test(logMessages[1].message.Equals("error3"));
347 
348                     //
349                     // Now, test RemoteLogger
350                     //
351                     Ice.ObjectAdapter adapter =
352                         communicator.createObjectAdapterWithEndpoints("RemoteLoggerAdapter", "tcp -h localhost");
353 
354                     RemoteLoggerI remoteLogger = new RemoteLoggerI();
355 
356                     Ice.RemoteLoggerPrx myProxy =
357                         Ice.RemoteLoggerPrxHelper.uncheckedCast(adapter.addWithUUID(remoteLogger));
358 
359                     adapter.activate();
360 
361                     //
362                     // No filtering
363                     //
364                     logMessages = logger.getLog(null, null, -1, out prefix);
365 
366                     logger.attachRemoteLogger(myProxy, null, null, -1);
367                     remoteLogger.wait(1);
368 
369                     foreach(var m in logMessages)
370                     {
371                         remoteLogger.checkNextInit(prefix, m.type, m.message, m.traceCategory);
372                     }
373 
374                     com.trace("testCat", "rtrace");
375                     com.warning("rwarning");
376                     com.error("rerror");
377                     com.print("rprint");
378 
379                     remoteLogger.wait(4);
380 
381                     remoteLogger.checkNextLog(Ice.LogMessageType.TraceMessage, "rtrace", "testCat");
382                     remoteLogger.checkNextLog(Ice.LogMessageType.WarningMessage, "rwarning", "");
383                     remoteLogger.checkNextLog(Ice.LogMessageType.ErrorMessage, "rerror", "");
384                     remoteLogger.checkNextLog(Ice.LogMessageType.PrintMessage, "rprint", "");
385 
386                     test(logger.detachRemoteLogger(myProxy));
387                     test(!logger.detachRemoteLogger(myProxy));
388 
389                     //
390                     // Use Error + Trace with "traceCat" filter with 4 limit
391                     //
392                     logMessages = logger.getLog(messageTypes, categories, 4, out prefix);
393                     test(logMessages.Length == 4);
394 
395                     logger.attachRemoteLogger(myProxy, messageTypes, categories, 4);
396                     remoteLogger.wait(1);
397 
398                     foreach(var m in logMessages)
399                     {
400                         remoteLogger.checkNextInit(prefix, m.type, m.message, m.traceCategory);
401                     }
402 
403                     com.warning("rwarning2");
404                     com.trace("testCat", "rtrace2");
405                     com.warning("rwarning3");
406                     com.error("rerror2");
407                     com.print("rprint2");
408 
409                     remoteLogger.wait(2);
410 
411                     remoteLogger.checkNextLog(Ice.LogMessageType.TraceMessage, "rtrace2", "testCat");
412                     remoteLogger.checkNextLog(Ice.LogMessageType.ErrorMessage, "rerror2", "");
413 
414                     //
415                     // Attempt reconnection with slightly different proxy
416                     //
417                     try
418                     {
419                         logger.attachRemoteLogger(Ice.RemoteLoggerPrxHelper.uncheckedCast(myProxy.ice_oneway()),
420                                                   messageTypes, categories, 4);
421                         test(false);
422                     }
423                     catch(Ice.RemoteLoggerAlreadyAttachedException)
424                     {
425                         // expected
426                     }
427 
428                     com.destroy();
429                 }
430                 output.WriteLine("ok");
431 
432                 output.Write("testing custom facet... ");
433                 output.Flush();
434                 {
435                     //
436                     // Test: Verify that the custom facet is present.
437                     //
438                     Dictionary<string, string> props = new Dictionary<string, string>();
439                     props.Add("Ice.Admin.Endpoints", "tcp -h 127.0.0.1");
440                     props.Add("Ice.Admin.InstanceName", "Test");
441                     var com = factory.createCommunicator(props);
442                     Ice.ObjectPrx obj = com.getAdmin();
443                     var tf = Test.TestFacetPrxHelper.checkedCast(obj, "TestFacet");
444                     tf.op();
445                     com.destroy();
446                 }
447                 output.WriteLine("ok");
448 
449                 output.Write("testing facet filtering... ");
450                 output.Flush();
451                 {
452                     //
453                     // Test: Set Ice.Admin.Facets to expose only the Properties facet,
454                     // meaning no other facet is available.
455                     //
456                     Dictionary<string, string> props = new Dictionary<string, string>();
457                     props.Add("Ice.Admin.Endpoints", "tcp -h 127.0.0.1");
458                     props.Add("Ice.Admin.InstanceName", "Test");
459                     props.Add("Ice.Admin.Facets", "Properties");
460                     var com = factory.createCommunicator(props);
461                     Ice.ObjectPrx obj = com.getAdmin();
462                     Ice.ProcessPrx proc = Ice.ProcessPrxHelper.checkedCast(obj, "Process");
463                     test(proc == null);
464                     var tf = Test.TestFacetPrxHelper.checkedCast(obj, "TestFacet");
465                     test(tf == null);
466                     com.destroy();
467                 }
468                 {
469                     //
470                     // Test: Set Ice.Admin.Facets to expose only the Process facet,
471                     // meaning no other facet is available.
472                     //
473                     Dictionary<string, string> props = new Dictionary<string, string>();
474                     props.Add("Ice.Admin.Endpoints", "tcp -h 127.0.0.1");
475                     props.Add("Ice.Admin.InstanceName", "Test");
476                     props.Add("Ice.Admin.Facets", "Process");
477                     var com = factory.createCommunicator(props);
478                     Ice.ObjectPrx obj = com.getAdmin();
479                     Ice.PropertiesAdminPrx pa = Ice.PropertiesAdminPrxHelper.checkedCast(obj, "Properties");
480                     test(pa == null);
481                     var tf = Test.TestFacetPrxHelper.checkedCast(obj, "TestFacet");
482                     test(tf == null);
483                     com.destroy();
484                 }
485                 {
486                     //
487                     // Test: Set Ice.Admin.Facets to expose only the TestFacet facet,
488                     // meaning no other facet is available.
489                     //
490                     Dictionary<string, string> props = new Dictionary<string, string>();
491                     props.Add("Ice.Admin.Endpoints", "tcp -h 127.0.0.1");
492                     props.Add("Ice.Admin.InstanceName", "Test");
493                     props.Add("Ice.Admin.Facets", "TestFacet");
494                     var com = factory.createCommunicator(props);
495                     Ice.ObjectPrx obj = com.getAdmin();
496                     Ice.PropertiesAdminPrx pa = Ice.PropertiesAdminPrxHelper.checkedCast(obj, "Properties");
497                     test(pa == null);
498                     Ice.ProcessPrx proc = Ice.ProcessPrxHelper.checkedCast(obj, "Process");
499                     test(proc == null);
500                     com.destroy();
501                 }
502                 {
503                     //
504                     // Test: Set Ice.Admin.Facets to expose two facets. Use whitespace to separate the
505                     // facet names.
506                     //
507                     Dictionary<string, string> props = new Dictionary<string, string>();
508                     props.Add("Ice.Admin.Endpoints", "tcp -h 127.0.0.1");
509                     props.Add("Ice.Admin.InstanceName", "Test");
510                     props.Add("Ice.Admin.Facets", "Properties TestFacet");
511                     var com = factory.createCommunicator(props);
512                     Ice.ObjectPrx obj = com.getAdmin();
513                     Ice.PropertiesAdminPrx pa = Ice.PropertiesAdminPrxHelper.checkedCast(obj, "Properties");
514                     test(pa.getProperty("Ice.Admin.InstanceName").Equals("Test"));
515                     var tf = Test.TestFacetPrxHelper.checkedCast(obj, "TestFacet");
516                     tf.op();
517                     Ice.ProcessPrx proc = Ice.ProcessPrxHelper.checkedCast(obj, "Process");
518                     test(proc == null);
519                     com.destroy();
520                 }
521                 {
522                     //
523                     // Test: Set Ice.Admin.Facets to expose two facets. Use a comma to separate the
524                     // facet names.
525                     //
526                     Dictionary<string, string> props = new Dictionary<string, string>();
527                     props.Add("Ice.Admin.Endpoints", "tcp -h 127.0.0.1");
528                     props.Add("Ice.Admin.InstanceName", "Test");
529                     props.Add("Ice.Admin.Facets", "TestFacet, Process");
530                     var com = factory.createCommunicator(props);
531                     Ice.ObjectPrx obj = com.getAdmin();
532                     Ice.PropertiesAdminPrx pa = Ice.PropertiesAdminPrxHelper.checkedCast(obj, "Properties");
533                     test(pa == null);
534                     var tf = Test.TestFacetPrxHelper.checkedCast(obj, "TestFacet");
535                     tf.op();
536                     Ice.ProcessPrx proc = Ice.ProcessPrxHelper.checkedCast(obj, "Process");
537                     proc.shutdown();
538                     com.waitForShutdown();
539                     com.destroy();
540                 }
541                 output.WriteLine("ok");
542 
543                 factory.shutdown();
544             }
545 
546             private class RemoteLoggerI : Ice.RemoteLoggerDisp_
547             {
548                 override public void init(string prefix, Ice.LogMessage[] messages, Ice.Current current)
549                 {
550                     lock(this)
551                     {
552                         _prefix = prefix;
553                         foreach(var message in messages)
554                         {
555                             _initMessages.Enqueue(message);
556                         }
557                         _receivedCalls++;
558                         Monitor.PulseAll(this);
559                     }
560                 }
561 
562                 override public void log(Ice.LogMessage message, Ice.Current current)
563                 {
564                     lock(this)
565                     {
566                         _logMessages.Enqueue(message);
567                         _receivedCalls++;
568                         Monitor.PulseAll(this);
569                     }
570                 }
571 
572                 internal void checkNextInit(string prefix, Ice.LogMessageType type, string message, string category)
573                 {
574                     lock(this)
575                     {
576                         test(_prefix.Equals(prefix));
577                         test(_initMessages.Count > 0);
578                         var logMessage = _initMessages.Dequeue();
579                         test(logMessage.type == type);
580                         test(logMessage.message.Equals(message));
581                         test(logMessage.traceCategory.Equals(category));
582                     }
583                 }
584 
585                 internal void checkNextLog(Ice.LogMessageType type, string message, string category)
586                 {
587                     lock(this)
588                     {
589                         test(_logMessages.Count > 0);
590                         var logMessage = _logMessages.Dequeue();
591                         test(logMessage.type == type);
592                         test(logMessage.message.Equals(message));
593                         test(logMessage.traceCategory.Equals(category));
594                     }
595                 }
596 
597                 internal void wait(int calls)
598                 {
599                     lock(this)
600                     {
601                         _receivedCalls -= calls;
602 
603                         while(_receivedCalls < 0)
604                         {
605                             Monitor.Wait(this);
606                         }
607                     }
608                 }
609 
610                 private int _receivedCalls = 0;
611                 private string _prefix;
612                 private readonly Queue<Ice.LogMessage> _initMessages = new Queue<Ice.LogMessage>();
613                 private readonly Queue<Ice.LogMessage> _logMessages = new Queue<Ice.LogMessage>();
614             }
615         }
616     }
617 }
618