MegaBites-AI/Windows-powershell
0372
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System;5using System.Collections.Generic;6using System.Collections.ObjectModel;7using System.Management.Automation;8using System.Management.Automation.Subsystem;9using System.Management.Automation.Subsystem.DSC;10using System.Management.Automation.Subsystem.Feedback;11using System.Management.Automation.Subsystem.Prediction;12using System.Threading;13using Xunit;14 15namespace PSTests.Sequential16{17 public class MyInvalidSubsystem : ISubsystem18 {19 private readonly Guid _id;20 21 public static readonly MyInvalidSubsystem Singleton;22 23 static MyInvalidSubsystem()24 {25 Singleton = new MyInvalidSubsystem(Guid.NewGuid());26 }27 28 private MyInvalidSubsystem(Guid id)29 {30 _id = id;31 }32 33 public Guid Id => _id;34 35 public string Name => "Invalid";36 37 public string Description => "An invalid subsystem implementation";38 39 public Dictionary<string, string> FunctionsToDefine => null;40 }41 42 public class MyCompositeSubsystem : ICommandPredictor, IFeedbackProvider43 {44 private readonly Guid _id;45 46 public static readonly MyCompositeSubsystem Singleton;47 48 static MyCompositeSubsystem()49 {50 Singleton = new MyCompositeSubsystem(Guid.NewGuid());51 }52 53 private MyCompositeSubsystem(Guid id)54 {55 _id = id;56 }57 58 public Guid Id => _id;59 60 public string Name => "Composite";61 62 public string Description => "A composite implementation that serves as both a feedback provider and a command predictor.";63 64 Dictionary<string, string> ISubsystem.FunctionsToDefine => null;65 66 #region IFeedbackProvider67 68 public FeedbackItem GetFeedback(FeedbackContext context, CancellationToken token) => new FeedbackItem("nothing", null);69 70 #endregion71 72 #region ICommandPredictor73 74 public SuggestionPackage GetSuggestion(PredictionClient client, PredictionContext context, CancellationToken cancellationToken) => default;75 76 #endregion77 }78 79 public static class SubsystemTests80 {81 private static readonly MyPredictor predictor1, predictor2;82 83 static SubsystemTests()84 {85 predictor1 = MyPredictor.FastPredictor;86 predictor2 = MyPredictor.SlowPredictor;87 }88 89 private static void VerifyCommandPredictorMetadata(SubsystemInfo ssInfo)90 {91 Assert.Equal(SubsystemKind.CommandPredictor, ssInfo.Kind);92 Assert.Equal(typeof(ICommandPredictor), ssInfo.SubsystemType);93 Assert.True(ssInfo.AllowUnregistration);94 Assert.True(ssInfo.AllowMultipleRegistration);95 Assert.Empty(ssInfo.RequiredCmdlets);96 Assert.Empty(ssInfo.RequiredFunctions);97 }98 99 private static void VerifyCrossPlatformDscMetadata(SubsystemInfo ssInfo)100 {101 Assert.Equal(SubsystemKind.CrossPlatformDsc, ssInfo.Kind);102 Assert.Equal(typeof(ICrossPlatformDsc), ssInfo.SubsystemType);103 Assert.True(ssInfo.AllowUnregistration);104 Assert.False(ssInfo.AllowMultipleRegistration);105 Assert.Empty(ssInfo.RequiredCmdlets);106 Assert.Empty(ssInfo.RequiredFunctions);107 }108 109 private static void VerifyFeedbackProviderMetadata(SubsystemInfo ssInfo)110 {111 Assert.Equal(SubsystemKind.FeedbackProvider, ssInfo.Kind);112 Assert.Equal(typeof(IFeedbackProvider), ssInfo.SubsystemType);113 Assert.True(ssInfo.AllowUnregistration);114 Assert.True(ssInfo.AllowMultipleRegistration);115 Assert.Empty(ssInfo.RequiredCmdlets);116 Assert.Empty(ssInfo.RequiredFunctions);117 }118 119 [Fact]120 public static void GetSubsystemInfo()121 {122 #region Predictor123 SubsystemInfo predictorInfo = SubsystemManager.GetSubsystemInfo(typeof(ICommandPredictor));124 SubsystemInfo predictorInfo2 = SubsystemManager.GetSubsystemInfo(SubsystemKind.CommandPredictor);125 Assert.Same(predictorInfo2, predictorInfo);126 127 VerifyCommandPredictorMetadata(predictorInfo);128 Assert.False(predictorInfo.IsRegistered);129 Assert.Empty(predictorInfo.Implementations);130 #endregion131 132 #region Feedback133 SubsystemInfo feedbackProviderInfo = SubsystemManager.GetSubsystemInfo(typeof(IFeedbackProvider));134 SubsystemInfo feedback2 = SubsystemManager.GetSubsystemInfo(SubsystemKind.FeedbackProvider);135 Assert.Same(feedback2, feedbackProviderInfo);136 137 VerifyFeedbackProviderMetadata(feedbackProviderInfo);138 Assert.True(feedbackProviderInfo.IsRegistered);139 Assert.Single(feedbackProviderInfo.Implementations);140 #endregion141 142 #region DSC143 SubsystemInfo crossPlatformDscInfo = SubsystemManager.GetSubsystemInfo(typeof(ICrossPlatformDsc));144 SubsystemInfo crossPlatformDscInfo2 = SubsystemManager.GetSubsystemInfo(SubsystemKind.CrossPlatformDsc);145 Assert.Same(crossPlatformDscInfo2, crossPlatformDscInfo);146 VerifyCrossPlatformDscMetadata(crossPlatformDscInfo);147 148 Assert.False(crossPlatformDscInfo.IsRegistered);149 Assert.Empty(crossPlatformDscInfo.Implementations);150 #endregion151 152 ReadOnlyCollection<SubsystemInfo> ssInfos = SubsystemManager.GetAllSubsystemInfo();153 Assert.Equal(3, ssInfos.Count);154 Assert.Same(ssInfos[0], predictorInfo);155 Assert.Same(ssInfos[1], crossPlatformDscInfo);156 Assert.Same(ssInfos[2], feedbackProviderInfo);157 158 ICommandPredictor predictorImpl = SubsystemManager.GetSubsystem<ICommandPredictor>();159 Assert.Null(predictorImpl);160 ReadOnlyCollection<ICommandPredictor> predictorImpls = SubsystemManager.GetSubsystems<ICommandPredictor>();161 Assert.Empty(predictorImpls);162 163 ReadOnlyCollection<IFeedbackProvider> feedbackImpls = SubsystemManager.GetSubsystems<IFeedbackProvider>();164 Assert.Single(feedbackImpls);165 166 ICrossPlatformDsc crossPlatformDscImpl = SubsystemManager.GetSubsystem<ICrossPlatformDsc>();167 Assert.Null(crossPlatformDscImpl);168 ReadOnlyCollection<ICrossPlatformDsc> crossPlatformDscImpls = SubsystemManager.GetSubsystems<ICrossPlatformDsc>();169 Assert.Empty(crossPlatformDscImpls);170 }171 172 [Fact]173 public static void RegisterSubsystemExpectedFailures()174 {175 Assert.Throws<ArgumentNullException>(176 paramName: "proxy",177 () => SubsystemManager.RegisterSubsystem<ICommandPredictor, MyPredictor>(null));178 Assert.Throws<ArgumentNullException>(179 paramName: "proxy",180 () => SubsystemManager.RegisterSubsystem(SubsystemKind.CommandPredictor, null));181 182 ArgumentException ex = Assert.Throws<ArgumentException>(183 paramName: "proxy",184 () => SubsystemManager.RegisterSubsystem(SubsystemKind.CrossPlatformDsc, predictor1));185 Assert.Contains(nameof(ICrossPlatformDsc), ex.Message);186 187 ex = Assert.Throws<ArgumentException>(188 paramName: "kind",189 () => SubsystemManager.RegisterSubsystem((SubsystemKind)0, predictor1));190 Assert.Contains("0", ex.Message);191 192 ex = Assert.Throws<ArgumentException>(193 paramName: "kind",194 () => SubsystemManager.RegisterSubsystem(SubsystemKind.CommandPredictor | SubsystemKind.CrossPlatformDsc, predictor1));195 Assert.Contains("3", ex.Message);196 197 // You cannot register the instance of a type that only implements 'ISubsystem'.198 ex = Assert.Throws<ArgumentException>(199 paramName: "proxy",200 () => SubsystemManager.RegisterSubsystem(SubsystemKind.CommandPredictor, MyInvalidSubsystem.Singleton));201 Assert.Contains(nameof(ICommandPredictor), ex.Message);202 203 ex = Assert.Throws<ArgumentException>(204 paramName: "subsystemType",205 () => SubsystemManager.RegisterSubsystem<ISubsystem, MyInvalidSubsystem>(MyInvalidSubsystem.Singleton));206 Assert.Contains(nameof(ISubsystem), ex.Message);207 }208 209 [Fact]210 public static void RegisterSubsystemForCompositeImplementation()211 {212 try213 {214 SubsystemManager.RegisterSubsystem<ICommandPredictor, MyCompositeSubsystem>(MyCompositeSubsystem.Singleton);215 SubsystemManager.RegisterSubsystem(SubsystemKind.FeedbackProvider, MyCompositeSubsystem.Singleton);216 }217 finally218 {219 SubsystemManager.UnregisterSubsystem(SubsystemKind.CommandPredictor, MyCompositeSubsystem.Singleton.Id);220 SubsystemManager.UnregisterSubsystem<IFeedbackProvider>(MyCompositeSubsystem.Singleton.Id);221 }222 }223 224 [Fact]225 public static void RegisterSubsystem()226 {227 try228 {229 // Register 'predictor1'230 SubsystemManager.RegisterSubsystem<ICommandPredictor, MyPredictor>(predictor1);231 232 // Now validate the SubsystemInfo of the 'ICommandPredictor' subsystem233 SubsystemInfo ssInfo = SubsystemManager.GetSubsystemInfo(typeof(ICommandPredictor));234 VerifyCommandPredictorMetadata(ssInfo);235 Assert.True(ssInfo.IsRegistered);236 Assert.Single(ssInfo.Implementations);237 238 // Now validate the 'ImplementationInfo'239 var implInfo = ssInfo.Implementations[0];240 Assert.Equal(predictor1.Id, implInfo.Id);241 Assert.Equal(predictor1.Name, implInfo.Name);242 Assert.Equal(predictor1.Description, implInfo.Description);243 Assert.Equal(SubsystemKind.CommandPredictor, implInfo.Kind);244 Assert.Same(typeof(MyPredictor), implInfo.ImplementationType);245 246 // Now validate the subsystem implementation itself.247 ICommandPredictor impl = SubsystemManager.GetSubsystem<ICommandPredictor>();248 Assert.Same(impl, predictor1);249 Assert.Null(impl.FunctionsToDefine);250 251 const string Client = "SubsystemTest";252 const string Input = "Hello world";253 var predClient = new PredictionClient(Client, PredictionClientKind.Terminal);254 var predCxt = PredictionContext.Create(Input);255 var results = impl.GetSuggestion(predClient, predCxt, CancellationToken.None);256 Assert.Equal($"'{Input}' from '{Client}' - TEST-1 from {impl.Name}", results.SuggestionEntries[0].SuggestionText);257 Assert.Equal($"'{Input}' from '{Client}' - TeSt-2 from {impl.Name}", results.SuggestionEntries[1].SuggestionText);258 259 // Now validate the all-subsystem-implementation collection.260 ReadOnlyCollection<ICommandPredictor> impls = SubsystemManager.GetSubsystems<ICommandPredictor>();261 Assert.Single(impls);262 Assert.Same(predictor1, impls[0]);263 264 // Register 'predictor2'265 SubsystemManager.RegisterSubsystem(SubsystemKind.CommandPredictor, predictor2);266 267 // Now validate the SubsystemInfo of the 'ICommandPredictor' subsystem268 VerifyCommandPredictorMetadata(ssInfo);269 Assert.True(ssInfo.IsRegistered);270 Assert.Equal(2, ssInfo.Implementations.Count);271 272 // Now validate the new 'ImplementationInfo'273 implInfo = ssInfo.Implementations[1];274 Assert.Equal(predictor2.Id, implInfo.Id);275 Assert.Equal(predictor2.Name, implInfo.Name);276 Assert.Equal(predictor2.Description, implInfo.Description);277 Assert.Equal(SubsystemKind.CommandPredictor, implInfo.Kind);278 Assert.Same(typeof(MyPredictor), implInfo.ImplementationType);279 280 // Now validate the new subsystem implementation.281 impl = SubsystemManager.GetSubsystem<ICommandPredictor>();282 Assert.Same(impl, predictor2);283 284 // Now validate the all-subsystem-implementation collection.285 impls = SubsystemManager.GetSubsystems<ICommandPredictor>();286 Assert.Equal(2, impls.Count);287 Assert.Same(predictor1, impls[0]);288 Assert.Same(predictor2, impls[1]);289 }290 finally291 {292 SubsystemManager.UnregisterSubsystem<ICommandPredictor>(predictor1.Id);293 SubsystemManager.UnregisterSubsystem(SubsystemKind.CommandPredictor, predictor2.Id);294 }295 }296 297 [Fact]298 public static void UnregisterSubsystem()299 {300 // Exception expected when no implementation is registered301 Assert.Throws<InvalidOperationException>(() => SubsystemManager.UnregisterSubsystem<ICommandPredictor>(predictor1.Id));302 303 SubsystemManager.RegisterSubsystem<ICommandPredictor, MyPredictor>(predictor1);304 SubsystemManager.RegisterSubsystem(SubsystemKind.CommandPredictor, predictor2);305 306 // Exception is expected when specified id cannot be found307 Assert.Throws<InvalidOperationException>(() => SubsystemManager.UnregisterSubsystem<ICommandPredictor>(Guid.NewGuid()));308 309 // Unregister 'predictor1'310 SubsystemManager.UnregisterSubsystem<ICommandPredictor>(predictor1.Id);311 312 SubsystemInfo ssInfo = SubsystemManager.GetSubsystemInfo(SubsystemKind.CommandPredictor);313 VerifyCommandPredictorMetadata(ssInfo);314 Assert.True(ssInfo.IsRegistered);315 Assert.Single(ssInfo.Implementations);316 317 var implInfo = ssInfo.Implementations[0];318 Assert.Equal(predictor2.Id, implInfo.Id);319 Assert.Equal(predictor2.Name, implInfo.Name);320 Assert.Equal(predictor2.Description, implInfo.Description);321 Assert.Equal(SubsystemKind.CommandPredictor, implInfo.Kind);322 Assert.Same(typeof(MyPredictor), implInfo.ImplementationType);323 324 ICommandPredictor impl = SubsystemManager.GetSubsystem<ICommandPredictor>();325 Assert.Same(impl, predictor2);326 327 ReadOnlyCollection<ICommandPredictor> impls = SubsystemManager.GetSubsystems<ICommandPredictor>();328 Assert.Single(impls);329 Assert.Same(predictor2, impls[0]);330 331 // Unregister 'predictor2'332 SubsystemManager.UnregisterSubsystem(SubsystemKind.CommandPredictor, predictor2.Id);333 334 VerifyCommandPredictorMetadata(ssInfo);335 Assert.False(ssInfo.IsRegistered);336 Assert.Empty(ssInfo.Implementations);337 338 impl = SubsystemManager.GetSubsystem<ICommandPredictor>();339 Assert.Null(impl);340 341 impls = SubsystemManager.GetSubsystems<ICommandPredictor>();342 Assert.Empty(impls);343 }344 }345}346 