public async Task ReadMultipleObjects() { Mocks.StringPipe stringPipe = new Mocks.StringPipe(); Mocks.StringPipe outputPipe = new Mocks.StringPipe(); SimpleObject data1 = new SimpleObject() { BooleanProp = true, StringProp = "test", NumberProp = 456, }; SimpleObject data2 = new SimpleObject() { BooleanProp = false, StringProp = "test2", NumberProp = 123, }; stringPipe.BufferJsonRpcBlock(new object[] { data1, data2 }); JsonRpcPipe reader = new JsonRpcPipe(stringPipe, outputPipe); SimpleObject result = await reader.ReadBlock <SimpleObject>(); Assert.Equal(data1.StringProp, result.StringProp); Assert.Equal(data1.BooleanProp, result.BooleanProp); Assert.Equal(data1.NumberProp, result.NumberProp); result = await reader.ReadBlock <SimpleObject>(); Assert.Equal(data2.StringProp, result.StringProp); Assert.Equal(data2.BooleanProp, result.BooleanProp); Assert.Equal(data2.NumberProp, result.NumberProp); }
public async Task ReadSimpleObject() { Mocks.StringPipe stringPipe = new Mocks.StringPipe(); Mocks.StringPipe outputPipe = new Mocks.StringPipe(); SimpleObject data = new SimpleObject(); data.BooleanProp = true; data.StringProp = "test"; data.NumberProp = 456; stringPipe.BufferJsonRpcBlock(data); JsonRpcPipe reader = new JsonRpcPipe(stringPipe, outputPipe); SimpleObject result = await reader.ReadBlock <SimpleObject>(); Assert.Equal(data.StringProp, result.StringProp); Assert.Equal(data.BooleanProp, result.BooleanProp); Assert.Equal(data.NumberProp, result.NumberProp); }
public async Task WriteMessageWithHeaders() { Mocks.StringPipe stringPipe = new Mocks.StringPipe(); Mocks.StringPipe outputPipe = new Mocks.StringPipe(); SimpleObject data = new SimpleObject() { BooleanProp = true, StringProp = "test", NumberProp = 456, }; JsonRpcPipe reader = new JsonRpcPipe(stringPipe, outputPipe); await reader.WriteBlock <SimpleObject>(data); string output = outputPipe.OutputBuffer.ToString(); Assert.Equal("Content-Length: 57\r\nContent-Type: application/vscode-jsonrpc; charset=utf-8\r\n\r\n{\"StringProp\":\"test\",\"BooleanProp\":true,\"NumberProp\":456}\r\n", output); }
public async Task ReadMessageWithOptionalHeaders() { Mocks.StringPipe stringPipe = new Mocks.StringPipe(); Mocks.StringPipe outputPipe = new Mocks.StringPipe(); SimpleObject data = new SimpleObject() { BooleanProp = true, StringProp = "test", NumberProp = 456, }; stringPipe.BufferJsonRpcBlock(data, type: "test"); JsonRpcPipe reader = new JsonRpcPipe(stringPipe, outputPipe); SimpleObject result = await reader.ReadBlock <SimpleObject>(); Assert.Equal(data.StringProp, result.StringProp); Assert.Equal(data.BooleanProp, result.BooleanProp); Assert.Equal(data.NumberProp, result.NumberProp); }
public async Task ReadSubclassRelationship() { Mocks.StringPipe stringPipe = new Mocks.StringPipe(); Mocks.StringPipe outputPipe = new Mocks.StringPipe(); SubObject data = new SubObject() { StringProp = "test", BooleanProp = true, NumberProp = 456, Id = 12345 }; stringPipe.BufferJsonRpcBlock(data); JsonRpcPipe reader = new JsonRpcPipe(stringPipe, outputPipe); SubObject result = await reader.ReadBlock <SubObject>(); Assert.Equal(data.StringProp, result.StringProp); Assert.Equal(data.BooleanProp, result.BooleanProp); Assert.Equal(data.NumberProp, result.NumberProp); Assert.Equal(data.Id, result.Id); }
public async Task ReadParentChildRelationship() { Mocks.StringPipe stringPipe = new Mocks.StringPipe(); Mocks.StringPipe outputPipe = new Mocks.StringPipe(); ParentChildObject data = new ParentChildObject(); data.ParentProp = "parent"; data.Child = new SimpleObject() { StringProp = "test", BooleanProp = true, NumberProp = 456 }; stringPipe.BufferJsonRpcBlock(data); JsonRpcPipe reader = new JsonRpcPipe(stringPipe, outputPipe); ParentChildObject result = await reader.ReadBlock <ParentChildObject>(); Assert.Equal(data.ParentProp, result.ParentProp); Assert.NotNull(data.Child); Assert.Equal(data.Child.StringProp, result.Child.StringProp); Assert.Equal(data.Child.BooleanProp, result.Child.BooleanProp); Assert.Equal(data.Child.NumberProp, result.Child.NumberProp); }
public async Task RunAsync() { if (this.IsRunning) { throw new InvalidOperationException("Server is already running."); } // Retrieve all module information using the current runspace manager this.currentModule = this.parameters.RunspaceManager.GetModuleInfo(this.parameters.ModulePath); this.currentModule.Logger = this.parameters.Logger; // Parse specifications/metadata files for extra information, e.g. parameter renaming if (this.parameters.SpecificationPaths != null) { foreach (string specificationPath in this.parameters.SpecificationPaths) { if (this.parameters.Logger != null) { this.parameters.Logger.LogAsync("Loading specification file: " + specificationPath); } Json.JsonPathFinder jsonFinder = new Json.JsonPathFinder(File.ReadAllText(specificationPath)); if (this.parameters.Logger != null) { this.parameters.Logger.LogAsync("Parsing specification file: " + specificationPath); } this.currentModule.LoadMetadataFromSpecification(jsonFinder); } } this.currentModule.CompleteMetadataLoad(); // For JSON-RPC pipe input/output, add Newtonsoft.Json converters Newtonsoft.Json.JsonSerializerSettings inputSerializerSettings = null; if (this.Input is JsonRpcPipe) { JsonRpcPipe jsonRpcPipe = (JsonRpcPipe)this.Input; inputSerializerSettings = jsonRpcPipe.JsonSerializerSettings; new LiveTestRequestConverter(this.currentModule).RegisterSelf(jsonRpcPipe.JsonSerializerSettings); if (this.parameters.Logger != null) { this.parameters.Logger.JsonSerializerSettings = jsonRpcPipe.JsonSerializerSettings; } } if (this.Output is JsonRpcPipe) { JsonRpcPipe jsonRpcPipe = (JsonRpcPipe)this.Output; // Double check this is a different object than the input pipe, if any. if (inputSerializerSettings == null || inputSerializerSettings != jsonRpcPipe.JsonSerializerSettings) { new LiveTestRequestConverter(this.currentModule).RegisterSelf(jsonRpcPipe.JsonSerializerSettings); if (this.parameters.Logger != null) { this.parameters.Logger.JsonSerializerSettings = jsonRpcPipe.JsonSerializerSettings; } } } this.IsRunning = true; // Start message read thread this.messageReadThread = new Thread(async() => { while (this.IsRunning) { try { // Block and wait for the next request LiveTestRequest msg = await this.Input.ReadBlock <LiveTestRequest>(); if (this.IsRunning) { if (msg == null) { if (this.parameters.Logger != null) { this.parameters.Logger.LogAsync("Input stream has been closed, stopping server.", msg); } this.IsRunning = false; } else { if (this.parameters.Logger != null) { this.parameters.Logger.LogAsync("Processing message: {0}", msg); } Task.Run(() => { LiveTestResponse response = null; IServiceTracer serviceTracer = null; try { // Enable service tracing so that we can get service layer information required by test protocol long invocationId = this.parameters.TracingManager.GetNextInvocationId(); serviceTracer = this.parameters.TracingManager.CreateTracer(invocationId, this.parameters.Logger); this.parameters.TracingManager.EnableTracing(); // Process teh request CommandExecutionResult commandResult = this.currentModule.ProcessRequest(msg, this.parameters.CredentialFactory); if (commandResult == null) { if (this.parameters.Logger != null) { this.parameters.Logger.LogAsync("Command not found."); } response = msg.MakeResponse(null, MethodNotFound); } else { response = msg.MakeResponse(commandResult, serviceTracer, parameters.ObjectTransforms, this.parameters.Logger); } } catch (Exception exRequest) { if (this.parameters.Logger != null) { this.parameters.Logger.LogError("Exception processing request: " + exRequest.ToString()); } response = msg.MakeResponse(exRequest, InternalError); } finally { if (response != null) { this.Output.WriteBlock(response); } if (serviceTracer != null) { this.parameters.TracingManager.RemoveTracer(serviceTracer); } } }); } } } catch (Exception eRead) { if (this.parameters.Logger != null) { this.parameters.Logger.LogError("Exception during test server message loop: " + eRead.ToString()); } this.IsRunning = false; } } }) { IsBackground = true }; this.messageReadThread.Start(); if (this.parameters.Logger != null) { this.parameters.Logger.LogAsync("PowerShell live test server has started."); } }
static void Main(string[] args) { ServerArgs serverArgs = new ServerArgs().Parse(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "config.json")).Parse(args).Validate(); EventLogOutputPipe eventLogOutputPipe = new EventLogOutputPipe(); CompositeLogger logger = new CompositeLogger(); if (serverArgs.EnableEventLog) { logger.AddLogger(new Logger(eventLogOutputPipe, eventLogOutputPipe)); } if (serverArgs.EnablePipeLog) { try { NamedPipeServer namedPipe = new NamedPipeServer(serverArgs.LogPipeName); Logger namedPipeLogger = new Logger(namedPipe, namedPipe); logger.AddLogger(namedPipeLogger); } catch (Exception e) { logger.LogError("Failed to initialize named pipe logger: " + e.Message); } } if (serverArgs.Errors.Count > 0) { logger.LogError("Server arguments had errors."); foreach (string error in serverArgs.Errors) { logger.LogError(error); } return; } // Load external modules PowerShellRunspace runspace = new PowerShellRunspace(logger); foreach (string externalModule in serverArgs.ExternalModules) { GeneratedModule module = new GeneratedModule(runspace); module.ModulePath = externalModule; CommandExecutionResult result = module.Load(); if (result != null && result.HadErrors) { logger.LogError(String.Format(CultureInfo.CurrentCulture, "Failed to load extra module: {0}", externalModule)); result.LogErrors(logger); return; } } // Start test server JsonRpcPipe jsonRpcPipe = new JsonRpcPipe(new StandardInputPipe(), new StandardOutputPipe()); LiveTestServer server = new LiveTestServer(new LiveTestServerStartParams() { Logger = logger, Input = jsonRpcPipe, Output = jsonRpcPipe, CredentialFactory = new LiveTestCredentialFactory(), RunspaceManager = runspace, ModulePath = serverArgs.ModulePath, TracingManager = new ServiceTracingManager(), SpecificationPaths = serverArgs.SpecificationPaths, ObjectTransforms = serverArgs.GetTransforms() }); try { server.RunAsync().Wait(); } catch (Exception ex) { logger.LogError("Failed to start server: " + ex.ToString()); } // Wait until server exits (usually means the server ran into an internal error) while (server.IsRunning) { Thread.Sleep(2); } }