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);
        }
Exemple #7
0
        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.");
            }
        }
Exemple #8
0
        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);
            }
        }