예제 #1
0
        public async Task when_a_KernelEventEnvelope_is_received_it_publishes_the_event()
        {
            var kernelEvent = new CommandSucceeded(new SubmitCode("x=1"));
            var message     = KernelEventEnvelope.Serialize(KernelEventEnvelope.Create(kernelEvent));

            using var stringReader = new StringReader(message);
            var receiver = new KernelCommandAndEventTextReceiver(stringReader);

            var d = await receiver.CommandsAndEventsAsync(CancellationToken.None).FirstAsync();

            d.Event.Should().BeEquivalentTo(kernelEvent);
        }
예제 #2
0
        public async Task when_a_KernelEvent_is_sent_it_writes_a_KernelEventEnvelope()
        {
            var kernelEvent = new CommandSucceeded(new SubmitCode("x=1"));
            var buffer      = new StringBuilder();

            var sender = new KernelCommandAndEventTextStreamSender(new StringWriter(buffer));
            await sender.SendAsync(kernelEvent, CancellationToken.None);

            var envelopeMessage = buffer.ToString();

            envelopeMessage.Should()
            .BeEquivalentTo(KernelEventEnvelope.Serialize(KernelEventEnvelope.Create(kernelEvent)) + KernelCommandAndEventTextStreamSender.Delimiter);
        }
예제 #3
0
#pragma warning disable 1591 // Xml Comments

        public void Succeeded(CommandSucceeded callback)
        {
            ((ICanProcessCommandProcess)Proxy).AddSucceeded(callback);
        }
예제 #4
0
 public void AddSucceeded(CommandSucceeded callback)
 {
     _commandSucceededCallbacks.Add(new WeakDelegate(callback));
 }
예제 #5
0
 public void Succeeded(CommandSucceeded callback)
 {
     throw new System.NotImplementedException();
 }
예제 #6
0
        /// <summary>
        /// Runs a command with the given console context.
        /// </summary>
        /// <param name="command">The command (including raw arguments) to parse and run.</param>
        /// <param name="console">The <see cref="ConsoleContext"/> to run the command in.</param>
        /// <returns>Whether the command was actually found.</returns>
        public bool RunCommand(string command, ConsoleContext console)
        {
            //First we need to parse the command string into something we can actually use as a query.
            var query = ParseCommand(command);

            //If query is null, don't try to run a command. There was no command.
            if (query == null)
            {
                return(false);
            }
            //If we get to this stage, the query is OK. Let's find a local command.
            var local = _localCommands.FirstOrDefault(x => x.Name == query.Name);

            //If this is null we'll send it off to the server. Well, I haven't implemented the server yet so we'll just return false.
            if (local == null)
            {
                if (!_server.Connected)
                {
                    return(false);
                }
                using (var memstr = new MemoryStream())
                {
                    using (var writer = new BinaryWriter(memstr, Encoding.UTF8))
                    {
                        writer.Write(query.Name);
                        writer.Write(query.ArgumentTokens.Length);
                        foreach (var token in query.ArgumentTokens)
                        {
                            writer.Write(token);
                        }
                        writer.Flush();
                        ManualResetEvent commandDone = new ManualResetEvent(false);

                        Action <ServerBroadcastType, BinaryReader> terminalOutput = (req, r) =>
                        {
                            if (req != ServerBroadcastType.TerminalOutput)
                            {
                                return;
                            }
                            int    count = r.ReadInt32();
                            byte[] data  = r.ReadBytes(count);
                            string str   = Encoding.UTF8.GetString(data);
                            console.Write(str);
                            if (str.ToCharArray().Contains((char)0x02))
                            {
                                commandDone.Set();
                            }
                        };
                        _server.BroadcastReceived += terminalOutput;

                        Stream remoteSlave = null;
                        Thread t           = null;

                        _server.SendMessage(ServerMessageType.TRM_INVOKE, memstr.ToArray(), (res, reader) =>
                        {
                            if (res != ServerResponseType.REQ_SUCCESS)
                            {
                                console.WriteLine("Unexpected, unknown error.");
                                return;
                            }
                            int remoteSlaveId = reader.ReadInt32();

                            remoteSlave = _remoteStreams.Open(remoteSlaveId);

                            t = new Thread(() =>
                            {
                                while (true)
                                {
                                    try
                                    {
                                        char input = (char)console.StandardInput.BaseStream.ReadByte();
                                        remoteSlave.WriteByte((byte)input);
                                    }
                                    catch (TerminationRequestException)
                                    {
                                        remoteSlave.WriteByte(0x02);
                                        remoteSlave.WriteByte((byte)'\n');
                                    }
                                }
                            });

                            t.Start();
                        }).Wait();

                        commandDone.WaitOne();

                        CommandSucceeded?.Invoke(query.Name);

                        _server.BroadcastReceived -= terminalOutput;

                        t.Abort();
                        remoteSlave.Close();
                    }
                }
                return(true);
            }
            else
            {
                //So we have a command query, a console context, and a command.
                //What do we need next? Well, we need our argument dictionary.
                //We can use Docopt.Net and the ITerminalCommand.Usages property to get that.
                //First let's create a Dictionary<string, object> to store our arguments.
                var argumentStore = new Dictionary <string, object>();

                //Next, we retrieve the usage string from the command.
                //The engine creates usage strings during initialization.
                var usage = _usages[local.Name];

                //Then we pass it off to Docopt.
                var docoptArgs = new DocoptNet.Docopt().Apply(usage, query.ArgumentTokens, true, local.Name, false, false);
                //Now we just CTRL+C and CTRL+V from the debug console.
                foreach (var arg in docoptArgs)
                {
                    if (arg.Value != null)
                    {
                        argumentStore.Add(arg.Key, arg.Value.Value);
                    }
                    else
                    {
                        argumentStore.Add(arg.Key, null);
                    }
                }
                //Now we run the command - check for errors!
                try
                {
                    local.Run(console, argumentStore);
                    CommandSucceeded?.Invoke(query.Name);
                }
                catch (TerminationRequestException)
                {
                    console.WriteLine("Killed.");
                    return(true);
                }
                return(true);
            }
        }
예제 #7
0
#pragma warning disable 1591 // Xml Comments

        public void Succeeded(CommandSucceeded callback)
        {
            ((ICanProcessCommandProcess)Proxy).AddSucceeded(callback);
        }