[Fact] // Bizarre behavior when using the built-in Pipe class: https://github.com/dotnet/corefx/issues/31696
    public async Task CancelPendingRead()
    {
        var stream = new SimplexStream();
        var reader = this.CreatePipeReader(stream, sizeHint: 50);

        ValueTask<ReadResult> readTask = reader.ReadAsync(this.TimeoutToken);
        reader.CancelPendingRead();
        var readResult = await readTask.AsTask().WithCancellation(this.TimeoutToken);
        Assert.True(readResult.IsCanceled);
        ////reader.AdvanceTo(readResult.Buffer.End);

        // Verify we can read after that without cancellation.
        readTask = reader.ReadAsync(this.TimeoutToken);
        stream.Write(new byte[] { 1, 2, 3 }, 0, 3);
        await stream.FlushAsync(this.TimeoutToken);
        readResult = await readTask;
        Assert.False(readResult.IsCanceled);
        Assert.Equal(3, readResult.Buffer.Length);
        reader.AdvanceTo(readResult.Buffer.End);

        // Now cancel again
        readTask = reader.ReadAsync(this.TimeoutToken);
        reader.CancelPendingRead();
        readResult = await readTask;
        Assert.True(readResult.IsCanceled);
    }
    public async Task UsePipe_Stream_Disposal()
    {
        var         ms   = new SimplexStream();
        IDuplexPipe pipe = ms.UsePipe(cancellationToken: this.TimeoutToken);

        pipe.Output.Complete();
        pipe.Input.Complete();
        await this.AssertStreamClosesAsync(ms);
    }
Пример #3
0
        private Task CopyTo(SimplexStream stream)
        {
            var task = Task.Run(async delegate {
                Console.WriteLine("Starting Write!");
                var destination = new FileStream("D:\\temp\\target.msi", FileMode.Create, FileAccess.Write);
                await stream.CopyToAsync(destination);
            });

            return(task);
        }
Пример #4
0
    public async Task Complete_CausesWriterCompletion()
    {
        var stream = new SimplexStream();
        var reader = this.CreatePipeReader(stream);

#pragma warning disable CS0618 // Type or member is obsolete
        Task writerCompletion = reader.WaitForWriterCompletionAsync();
#pragma warning restore CS0618 // Type or member is obsolete
        reader.Complete();
        await writerCompletion.WithCancellation(this.TimeoutToken);
    }
Пример #5
0
        private Task CopyFrom(SimplexStream stream)
        {
            var task = Task.Run(async delegate {
                Console.WriteLine("Starting Read!");
                var source = new FileStream("C:\\temp\\LibreOffice_4.2.0_Win_x86.msi", FileMode.Open);
                await source.CopyToAsync(stream);
                stream.CompleteWriting();
            });

            return(task);
        }
    public async Task UsePipe_Stream()
    {
        var         ms   = new SimplexStream();
        IDuplexPipe pipe = ms.UsePipe(cancellationToken: this.TimeoutToken);
        await pipe.Output.WriteAsync(new byte[] { 1, 2, 3 }, this.TimeoutToken);

        var readResult = await pipe.Input.ReadAsync(this.TimeoutToken);

        Assert.Equal(3, readResult.Buffer.Length);
        pipe.Input.AdvanceTo(readResult.Buffer.End);
    }
Пример #7
0
        public async Task Read_Cancelled_ReturnsNull_Async()
        {
            var stream = new SimplexStream();

            using (var streamReader = new StreamReader(stream))
            {
                var cts  = new CancellationTokenSource();
                var task = streamReader.ReadLineAsync(cts.Token);
                cts.Cancel();

                Assert.Null(await task.ConfigureAwait(false));
            }
        }
Пример #8
0
        public async Task Copy()
        {
            var sourceStream = new SimplexStream();
            var tc           = CopyFrom(sourceStream);

            var targetStream = new SimplexStream();
            var td           = CopyTo(targetStream);

            Console.WriteLine("Copy in between");

            await sourceStream.CopyToAsync(targetStream);

            targetStream.CompleteWriting();

            await Task.WhenAll(tc, td);
        }
        private static async IAsyncEnumerable <NotebookParserServerResponse> GetResponseObjectsEnumerable(string inputText)
        {
            using var input = new StringReader(inputText);
            var stream       = new SimplexStream();
            var output       = new StreamWriter(stream);
            var server       = new NotebookParserServer(input, output);
            var _            = Task.Run(() => server.RunAsync()); // start server listener in the background
            var outputReader = new StreamReader(stream);

            while (true)
            {
                var responseText = await outputReader.ReadLineAsync();

                var responseObject = NotebookParserServerResponse.FromJson(responseText);
                yield return(responseObject);
            }
        }
Пример #10
0
        public async Task ReadLine_HasData_ReturnsValue_Async()
        {
            var stream = new SimplexStream();

            using (var streamReader = new StreamReader(stream))
                using (var streamWriter = new StreamWriter(stream))
                {
                    var cts  = new CancellationTokenSource();
                    var task = streamReader.ReadLineAsync(cts.Token);

                    await streamWriter.WriteLineAsync("Hello, World!".ToCharArray(), default).ConfigureAwait(false);

                    await streamWriter.FlushAsync().ConfigureAwait(false);

                    Assert.Equal("Hello, World!", await task.ConfigureAwait(false));
                }
        }
Пример #11
0
    public async Task ReadAsyncAfterExamining()
    {
        byte[] expectedBuffer = this.GetRandomBuffer(2048);
        var    stream         = new SimplexStream();

        stream.Write(expectedBuffer, 0, 50);
        await stream.FlushAsync(this.TimeoutToken);

        var reader = this.CreatePipeReader(stream, sizeHint: 50);

        byte[] actualBuffer = new byte[expectedBuffer.Length];

        ReadResult result = await reader.ReadAsync(this.TimeoutToken);

        reader.AdvanceTo(result.Buffer.Start, result.Buffer.GetPosition(1));

        // Since we didn't examine all the bytes already in the buffer, the next read should be synchronous,
        // and shouldn't give us any more buffer.
        ValueTask <ReadResult> resultTask = reader.ReadAsync(this.TimeoutToken);

        Assert.True(resultTask.IsCompleted);
        Assert.Equal(result.Buffer.Length, resultTask.Result.Buffer.Length);

        // Now examine everything, but don't consume it. We should get more.
        reader.AdvanceTo(resultTask.Result.Buffer.Start, resultTask.Result.Buffer.End);
        ValueTask <ReadResult> resultTask2 = reader.ReadAsync(this.TimeoutToken);

        Assert.False(resultTask2.IsCompleted);
        stream.Write(expectedBuffer, 50, 50);
        await stream.FlushAsync(this.TimeoutToken);

        var result2 = await resultTask2;

        Assert.True(result2.Buffer.Length > result.Buffer.Length);

        // Now consume everything and get even more.
        reader.AdvanceTo(result2.Buffer.End);
        stream.Write(expectedBuffer, 100, expectedBuffer.Length - 100);
        await stream.FlushAsync(this.TimeoutToken);

        ReadResult result3 = await reader.ReadAsync(this.TimeoutToken);

        Assert.True(result3.Buffer.Length > 0);
    }
Пример #12
0
        public async Task WatchNamespacedObjectAsync_ClientCanStopLoop_Async()
        {
            using (var stream = new SimplexStream())
                using (var writer = new StreamWriter(stream))
                {
                    var handler = new DummyHandler();
                    handler.Responses.Enqueue(
                        new HttpResponseMessage()
                    {
                        StatusCode = HttpStatusCode.OK,
                        Content    = new WatchHttpContent(
                            new StreamContent(stream)),
                    });

                    Collection <(WatchEventType, V1Pod)> events = new Collection <(WatchEventType, V1Pod)>();

                    var protocol = new KubernetesProtocol(handler, this.loggerFactory.CreateLogger <KubernetesProtocol>(), this.loggerFactory);
                    var cts      = new CancellationTokenSource();

                    var watchTask = protocol.WatchNamespacedObjectAsync(
                        new V1Pod()
                    {
                        Metadata = new V1ObjectMeta(name: "pod", namespaceProperty: "default", resourceVersion: "1"),
                    },
                        protocol.ListNamespacedPodWithHttpMessagesAsync,
                        (eventType, result) =>
                    {
                        events.Add((eventType, result));
                        return(Task.FromResult(events.Count == 1 ? WatchResult.Continue : WatchResult.Stop));
                    },
                        cts.Token);

                    Assert.True(!watchTask.IsCompleted);

                    await writer.WriteAsync(
                        JsonConvert.SerializeObject(
                            new V1WatchEvent()
                    {
                        Type           = nameof(WatchEventType.Deleted),
                        ObjectProperty = new V1Pod()
                        {
                            Metadata = new V1ObjectMeta()
                            {
                                NamespaceProperty = "some-namespace",
                                Name = "some-name",
                            },
                        },
                    }));

                    await writer.WriteAsync('\n').ConfigureAwait(false);

                    await writer.FlushAsync().ConfigureAwait(false);

                    Assert.True(!watchTask.IsCompleted);

                    await writer.WriteAsync(
                        JsonConvert.SerializeObject(
                            new V1WatchEvent()
                    {
                        Type           = nameof(WatchEventType.Deleted),
                        ObjectProperty = new V1Pod()
                        {
                            Metadata = new V1ObjectMeta()
                            {
                                NamespaceProperty = "some-namespace2",
                                Name = "some-name2",
                            },
                        },
                    }));

                    await writer.WriteAsync('\n').ConfigureAwait(false);

                    await writer.FlushAsync().ConfigureAwait(false);

                    var result = await watchTask;
                    Assert.Equal(WatchExitReason.ClientDisconnected, result);

                    Assert.Collection(
                        events,
                        e =>
                    {
                        Assert.Equal(WatchEventType.Deleted, e.Item1);
                        Assert.Equal("some-namespace", e.Item2.Metadata.NamespaceProperty);
                        Assert.Equal("some-name", e.Item2.Metadata.Name);
                    },
                        e =>
                    {
                        Assert.Equal(WatchEventType.Deleted, e.Item1);
                        Assert.Equal("some-namespace2", e.Item2.Metadata.NamespaceProperty);
                        Assert.Equal("some-name2", e.Item2.Metadata.Name);
                    });
                }
        }
Пример #13
0
        static void Main(string[] args)
        {
            FileDialogs.Init();

            var serverStream = new SimplexStream();
            var clientStream = new SimplexStream();
            var encoding     = new UTF8Encoding(false);
            var writer       = new StreamWriter(serverStream, encoding);
            var formatter    = new JsonMessageFormatter(encoding);

            Serializer.PrepareSerializer(formatter.JsonSerializer);
            var messageHandler = new NewLineDelimitedMessageHandler(clientStream, serverStream, formatter);
            var server         = new FullServer(messageHandler);

            server.Workspace.SettingsService.RegisterSetting(DisplaySettingsNames.Theme, typeof(string), "xp/98.css");

            server.Agent.IsReady += (o, e) =>
            {
                if (args.Length == 1)
                {
                    var _ = server.Workspace.ExecuteCommand("File.Open", args[0]);
                }
            };

            // try to load settings
            string[] settingsLines    = Array.Empty <string>();
            var      settingsFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".bcadconfig");

            try
            {
                settingsLines = File.ReadAllLines(settingsFilePath);
                server.Workspace.SettingsService.LoadFromLines(settingsLines);
                server.Workspace.Update(isDirty: false);
            }
            catch
            {
                // don't really care if it failed
            }

#if DEBUG
            var allowDebugging  = true;
            var logVerbosity    = 1;
            var clientArguments = new[] { "--", "debug" };
#else
            var allowDebugging  = false;
            var logVerbosity    = 0;
            var clientArguments = new[] { "--" };
#endif

            var window = new PhotinoWindow()
                         .SetUseOsDefaultSize(true)
                         .SetContextMenuEnabled(false)
                         .Center()
                         .SetDevToolsEnabled(allowDebugging)
                         .SetResizable(true)
                         .SetLogVerbosity(logVerbosity)
                         .RegisterWebMessageReceivedHandler((object sender, string message) =>
            {
                try
                {
                    // forward JSON from client to server
                    writer.WriteLine(message);
                    writer.Flush();
                }
                catch
                {
                    // don't let this die
                }
            });
            SetTitle(window, server.Workspace);

            window.RegisterCustomSchemeHandler("app", (object sender, string scheme, string url, out string contentType) =>
            {
                contentType = "text/javascript";
                var script  = $"var clientArguments = [{string.Join(", ", clientArguments.Select(arg => $"\"{arg}\""))}];";
                return(new MemoryStream(Encoding.UTF8.GetBytes(script)));
            });

            var fileSystemService = new FileSystemService(action =>
            {
                window.Invoke(action);
            });
            server.Workspace.RegisterService(fileSystemService);

            server.Workspace.WorkspaceChanged += (sender, args) => SetTitle(window, server.Workspace);

            var doHardClose = false;
            window.WindowClosing += (sender, args) =>
            {
                if (doHardClose)
                {
                    // close immediately
                    return(false);
                }

                if (server.Workspace.IsDirty)
                {
                    var _ = Task.Run(async() =>
                    {
                        var result = await server.Workspace.PromptForUnsavedChanges();
                        if (result != UnsavedChangesResult.Cancel)
                        {
                            doHardClose = true;
                            window.Close();
                        }
                    });

                    // don't close yet
                    return(true);
                }

                return(false);
            };

            var _ = Task.Run(async() =>
            {
                var reader = new StreamReader(clientStream, encoding);
                while (true)
                {
                    try
                    {
                        var line = await reader.ReadLineAsync();
                        window.SendWebMessage(line);
                    }
                    catch
                    {
                        // don't let this die
                    }
                }
            });

            server.Start();
            var indexPath = Path.Combine(AppContext.BaseDirectory, "wwwroot", "index.html");
            window.Load(indexPath);
            window.WaitForClose();

            // try to save settings
            try
            {
                var newSettingsContents = server.Workspace.SettingsService.WriteWithLines(settingsLines);
                File.WriteAllText(settingsFilePath, newSettingsContents);
            }
            catch
            {
                // don't really care if it failed
            }
        }
    public void DefaultCtor()
    {
        var stream = new SimplexStream();

        stream.Dispose();
    }