public async Task ExecDefaultContainerStdOut() { if (!Debugger.IsAttached) { CancellationSource.CancelAfter( TimeSpan.FromSeconds(5)); } await Host.StartAsync(TestCancellation).ConfigureAwait(false); using (Kubernetes client = CreateTestClient()) { testOutput.WriteLine("Invoking exec operation..."); WebSocket clientSocket = await client.WebSocketNamespacedPodExecAsync( "mypod", "mynamespace", new string[] { "/bin/bash" }, "mycontainer", false, false, true, webSocketSubProtol : WebSocketProtocol.ChannelWebSocketProtocol, cancellationToken : TestCancellation).ConfigureAwait(false); Assert.Equal( WebSocketProtocol.ChannelWebSocketProtocol, clientSocket.SubProtocol); // For WebSockets, the Kubernetes API defaults to the binary channel (v1) protocol. testOutput.WriteLine( $"Client socket connected (socket state is {clientSocket.State}). Waiting for server-side socket to become available..."); WebSocket serverSocket = await WebSocketTestAdapter.AcceptedPodExecV1Connection; testOutput.WriteLine( $"Server-side socket is now available (socket state is {serverSocket.State}). Sending data to server socket..."); const int STDOUT = 1; const string expectedOutput = "This is text send to STDOUT."; int bytesSent = await SendMultiplexed(serverSocket, STDOUT, expectedOutput).ConfigureAwait(false); testOutput.WriteLine($"Sent {bytesSent} bytes to server socket; receiving from client socket..."); (string receivedText, byte streamIndex, int bytesReceived) = await ReceiveTextMultiplexed(clientSocket).ConfigureAwait(false); testOutput.WriteLine( $"Received {bytesReceived} bytes from client socket ('{receivedText}', stream {streamIndex})."); Assert.Equal(STDOUT, streamIndex); Assert.Equal(expectedOutput, receivedText); await Disconnect(clientSocket, serverSocket, WebSocketCloseStatus.NormalClosure, "Normal Closure").ConfigureAwait(false); WebSocketTestAdapter.CompleteTest(); } }
/// <summary> /// Create a new <see cref="PodPortForwardController"/>. /// </summary> /// <param name="webSocketTestAdapter"> /// The adapter used to capture sockets accepted by the test server and provide them to the calling test. /// </param> public PodPortForwardController(WebSocketTestAdapter webSocketTestAdapter) { if (webSocketTestAdapter == null) { throw new ArgumentNullException(nameof(webSocketTestAdapter)); } WebSocketTestAdapter = webSocketTestAdapter; }
public async Task Exec_DefaultContainer_Raw_StdOut() { const string expectedOutput = "This is text sent to STDOUT."; TestTimeout( TimeSpan.FromSeconds(5) ); await Host.StartAsync(TestCancellation); using (KubeApiClient client = CreateTestClient()) { WebSocket clientSocket = await client.PodsV1().ExecAndConnectRaw( podName: "pod1", command: "/bin/bash", stdin: true, stdout: true, stderr: true ); Assert.Equal(K8sChannelProtocol.V1, clientSocket.SubProtocol); // For WebSockets, the Kubernetes API defaults to the binary channel (v1) protocol. using (clientSocket) { Log.LogInformation("Waiting for server-side WebSocket."); WebSocket serverSocket = await WebSocketTestAdapter.AcceptedPodExecV1Connection; int bytesSent = await SendMultiplexed(serverSocket, K8sChannel.StdOut, expectedOutput); Log.LogInformation("Sent {ByteCount} bytes to server socket; receiving from client socket...", bytesSent); (string receivedText, byte streamIndex, int bytesReceived) = await ReceiveTextMultiplexed(clientSocket); Log.LogInformation("Received {ByteCount} bytes from client socket ('{ReceivedText}', stream {StreamIndex}).", bytesReceived, receivedText, streamIndex); Assert.Equal(K8sChannel.StdOut, streamIndex); Assert.Equal(expectedOutput, receivedText); await Disconnect(clientSocket, serverSocket); WebSocketTestAdapter.Done(); } } }
public async Task Exec_DefaultContainer_Multiplexed_AllStreams() { const string expectedPrompt = "/root # "; const string expectedCommand = "ls -l /root"; TestTimeout( TimeSpan.FromSeconds(5) ); await Host.StartAsync(TestCancellation); using (KubeApiClient client = CreateTestClient()) { K8sMultiplexer multiplexer = await client.PodsV1().ExecAndConnect( podName: "pod1", command: "/bin/bash", stdin: true, stdout: true, stderr: true ); using (multiplexer) { Stream stdin = multiplexer.GetStdIn(); Stream stdout = multiplexer.GetStdOut(); Log.LogInformation("Waiting for server-side WebSocket."); WebSocket serverSocket = await WebSocketTestAdapter.AcceptedPodExecV1Connection; Log.LogInformation("Server sends prompt."); await SendMultiplexed(serverSocket, K8sChannel.StdOut, expectedPrompt); Log.LogInformation("Server sent prompt."); Log.LogInformation("Client expects prompt."); byte[] receiveBuffer = new byte[2048]; int bytesReceived = await stdout.ReadAsync(receiveBuffer, 0, receiveBuffer.Length, TestCancellation); string prompt = Encoding.ASCII.GetString(receiveBuffer, 0, bytesReceived); Assert.Equal(expectedPrompt, prompt); Log.LogInformation("Client got expected prompt."); Log.LogInformation("Client sends command."); byte[] sendBuffer = Encoding.ASCII.GetBytes(expectedCommand); await stdin.WriteAsync(sendBuffer, 0, sendBuffer.Length, TestCancellation); Log.LogInformation("Client sent command."); Log.LogInformation("Server expects command."); (string command, byte streamIndex, int totalBytes) = await ReceiveTextMultiplexed(serverSocket); Assert.Equal(K8sChannel.StdIn, streamIndex); Assert.Equal(expectedCommand, command); Log.LogInformation("Server got expected command."); Task closeServerSocket = WaitForClose(serverSocket, socketType: "server"); Log.LogInformation("Close enough; we're done."); await multiplexer.Shutdown(TestCancellation); await closeServerSocket; WebSocketTestAdapter.Done(); } } }