1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.Threading.Tasks;
6 using Xunit;
7 
8 namespace System.IO.Pipes.Tests
9 {
10     /// <summary>
11     /// Contains helper methods specifically for Named pipes
12     /// </summary>
13     public class NamedPipeTestBase : PipeTestBase
14     {
15         /// <summary>
16         /// Represents a Server-Client pair in which both pipes are specifically
17         /// Named Pipes. Used for tests that do not have an AnonymousPipe equivalent
18         /// </summary>
19         public class NamedPipePair : IDisposable
20         {
21             public NamedPipeServerStream serverStream;
22             public NamedPipeClientStream clientStream;
23             public bool writeToServer;     // True if the serverStream should be written to in one-way tests
24 
Dispose()25             public void Dispose()
26             {
27                 if (clientStream != null)
28                     clientStream.Dispose();
29                 serverStream.Dispose();
30             }
31 
Connect()32             public void Connect()
33             {
34                 Task clientConnect = clientStream.ConnectAsync();
35                 serverStream.WaitForConnection();
36                 clientConnect.Wait();
37             }
38         }
39 
CreateNamedPipePair()40         protected virtual NamedPipePair CreateNamedPipePair()
41         {
42             return CreateNamedPipePair(PipeOptions.Asynchronous, PipeOptions.Asynchronous);
43         }
44 
CreateNamedPipePair(PipeOptions serverOptions, PipeOptions clientOptions)45         protected virtual NamedPipePair CreateNamedPipePair(PipeOptions serverOptions, PipeOptions clientOptions)
46         {
47             return null;
48         }
49 
CreateServerClientPair()50         protected override ServerClientPair CreateServerClientPair()
51         {
52             ServerClientPair ret = new ServerClientPair();
53             string pipeName = GetUniquePipeName();
54             var readablePipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
55             var writeablePipe = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut);
56 
57             Task clientConnect = writeablePipe.ConnectAsync();
58             readablePipe.WaitForConnection();
59             clientConnect.Wait();
60 
61             ret.readablePipe = readablePipe;
62             ret.writeablePipe = writeablePipe;
63             return ret;
64         }
65 
ReadBytes(PipeStream pipeStream, int length)66         protected static byte[] ReadBytes(PipeStream pipeStream, int length)
67         {
68             Assert.True(pipeStream.IsConnected);
69 
70             byte[] buffer = new byte[length];
71             Assert.True(length > 0);
72 
73             buffer[0] = (byte)pipeStream.ReadByte();
74             if (length > 1)
75             {
76                 int len = pipeStream.Read(buffer, 1, length - 1);
77                 Assert.Equal(length - 1, len);
78             }
79 
80             return buffer;
81         }
82 
WriteBytes(PipeStream pipeStream, byte[] buffer)83         protected static void WriteBytes(PipeStream pipeStream, byte[] buffer)
84         {
85             Assert.True(pipeStream.IsConnected);
86             Assert.True(buffer.Length > 0);
87 
88             pipeStream.WriteByte(buffer[0]);
89             if (buffer.Length > 1)
90             {
91                 pipeStream.Write(buffer, 1, buffer.Length - 1);
92             }
93         }
94 
ReadBytesAsync(PipeStream pipeStream, int length)95         protected static async Task<byte[]> ReadBytesAsync(PipeStream pipeStream, int length)
96         {
97             Assert.True(pipeStream.IsConnected);
98 
99             byte[] buffer = new byte[length];
100             Assert.True(length > 0);
101 
102             int readSoFar = 0;
103 
104             while (readSoFar < length)
105             {
106                 int len = await pipeStream.ReadAsync(buffer, readSoFar, length - readSoFar);
107                 if (len == 0) break;
108                 readSoFar += len;
109             }
110 
111             return buffer;
112         }
113 
WriteBytesAsync(PipeStream pipeStream, byte[] buffer)114         protected static Task WriteBytesAsync(PipeStream pipeStream, byte[] buffer)
115         {
116             Assert.True(pipeStream.IsConnected);
117             Assert.True(buffer.Length > 0);
118             return pipeStream.WriteAsync(buffer, 0, buffer.Length);
119         }
120     }
121 }
122