@@ -5,7 +5,7 @@ use std::io;
55use std:: mem;
66use std:: os:: windows:: io:: AsRawHandle ;
77use std:: time:: Duration ;
8- use tokio:: io:: AsyncWriteExt ;
8+ use tokio:: io:: { AsyncReadExt , AsyncWriteExt } ;
99use tokio:: net:: windows:: named_pipe:: { ClientOptions , PipeMode , ServerOptions } ;
1010use tokio:: time;
1111use windows_sys:: Win32 :: Foundation :: { ERROR_NO_DATA , ERROR_PIPE_BUSY , NO_ERROR , UNICODE_STRING } ;
@@ -327,17 +327,53 @@ async fn test_named_pipe_multi_client_ready() -> io::Result<()> {
327327 Ok ( ( ) )
328328}
329329
330- // This tests what happens when a client tries to disconnect .
330+ // This tests that message mode works as expected .
331331#[ tokio:: test]
332332async fn test_named_pipe_mode_message ( ) -> io:: Result < ( ) > {
333- const PIPE_NAME : & str = r"\\.\pipe\test-named-pipe-mode-message" ;
333+ // it's easy to accidentally get a seemingly working test here because byte pipes
334+ // often return contents at write boundaries. to make sure we're doing the right thing we
335+ // explicitly test that it doesn't work in byte mode.
336+ _named_pipe_mode_message ( PipeMode :: Message ) . await ?;
337+ _named_pipe_mode_message ( PipeMode :: Byte ) . await
338+ }
339+
340+ async fn _named_pipe_mode_message ( mode : PipeMode ) -> io:: Result < ( ) > {
341+ let pipe_name = format ! (
342+ r"\\.\pipe\test-named-pipe-mode-message-{}" ,
343+ matches!( mode, PipeMode :: Message )
344+ ) ;
345+ let mut buf = [ 0u8 ; 32 ] ;
334346
335- let server = ServerOptions :: new ( )
336- . pipe_mode ( PipeMode :: Message )
337- . create ( PIPE_NAME ) ?;
347+ let mut server = ServerOptions :: new ( )
348+ . first_pipe_instance ( true )
349+ . pipe_mode ( mode)
350+ . create ( & pipe_name) ?;
351+
352+ let mut client = ClientOptions :: new ( )
353+ //.pipe_mode(mode)
354+ . open ( & pipe_name) ?;
338355
339- let _ = ClientOptions :: new ( ) . open ( PIPE_NAME ) ?;
340356 server. connect ( ) . await ?;
357+
358+ // this needs a few iterations, presumably Windows waits for a few calls before merging buffers
359+ for _ in 0 ..10 {
360+ client. write_all ( b"hello" ) . await ?;
361+ server. write_all ( b"world" ) . await ?;
362+ }
363+ for _ in 0 ..10 {
364+ let n = server. read ( & mut buf) . await ?;
365+ if buf[ ..n] != b"hello" [ ..] {
366+ assert ! ( matches!( mode, PipeMode :: Byte ) ) ;
367+ return Ok ( ( ) ) ;
368+ }
369+ let n = client. read ( & mut buf) . await ?;
370+ if buf[ ..n] != b"world" [ ..] {
371+ assert ! ( matches!( mode, PipeMode :: Byte ) ) ;
372+ return Ok ( ( ) ) ;
373+ }
374+ }
375+ // byte mode should have errored before.
376+ assert ! ( matches!( mode, PipeMode :: Message ) ) ;
341377 Ok ( ( ) )
342378}
343379
0 commit comments