go-hep.org/x/hep@v0.38.1/xrootd/server_test.go (about) 1 // Copyright ©2018 The go-hep Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package xrootd_test // import "go-hep.org/x/hep/xrootd" 6 7 import ( 8 "context" 9 "net" 10 "reflect" 11 "testing" 12 13 "go-hep.org/x/hep/xrootd" 14 "go-hep.org/x/hep/xrootd/internal/xrdenc" 15 "go-hep.org/x/hep/xrootd/xrdproto" 16 "go-hep.org/x/hep/xrootd/xrdproto/dirlist" 17 "go-hep.org/x/hep/xrootd/xrdproto/handshake" 18 "go-hep.org/x/hep/xrootd/xrdproto/login" 19 "go-hep.org/x/hep/xrootd/xrdproto/protocol" 20 ) 21 22 type pipeListener struct { 23 conns chan net.Conn 24 close chan struct{} 25 closed bool 26 } 27 28 func (pl *pipeListener) Close() error { 29 if pl.closed { 30 return nil 31 } 32 pl.closed = true 33 pl.close <- struct{}{} 34 return nil 35 } 36 37 func (pl *pipeListener) Addr() net.Addr { 38 panic("implement me") 39 } 40 41 func (pl *pipeListener) Accept() (net.Conn, error) { 42 select { 43 case conn := <-pl.conns: 44 return conn, nil 45 case <-pl.close: 46 return nil, closedError{} 47 } 48 } 49 50 type closedError struct { 51 } 52 53 func (closedError) Error() string { 54 return "xrootd: pipe listener closed" 55 } 56 57 func TestServe_Handshake(t *testing.T) { 58 connsCh := make(chan net.Conn, 1) 59 p1, p2 := net.Pipe() 60 defer p1.Close() 61 defer p2.Close() 62 63 connsCh <- p1 64 listener := &pipeListener{conns: connsCh, close: make(chan struct{})} 65 defer listener.Close() 66 67 srv := xrootd.NewServer(xrootd.Default(), func(err error) { 68 t.Error(err) 69 }) 70 defer func() { 71 _ = srv.Shutdown(context.Background()) 72 }() 73 74 go func() { 75 req := handshake.NewRequest() 76 var wBuffer xrdenc.WBuffer 77 err := req.MarshalXrd(&wBuffer) 78 if err != nil { 79 t.Errorf("could not marshal request: %+v", err) 80 } 81 _, err = p2.Write(wBuffer.Bytes()) 82 if err != nil { 83 t.Errorf("could not write buffer: %+v", err) 84 } 85 respHeader, respData, err := xrdproto.ReadResponse(p2) 86 if err != nil { 87 t.Errorf("unexpected read error: %v", err) 88 } 89 90 var ( 91 handshakeResp handshake.Response 92 rBuffer = xrdenc.NewRBuffer(respData) 93 ) 94 95 if err := handshakeResp.UnmarshalXrd(rBuffer); err != nil { 96 t.Errorf("could not unmarshal: %v", err) 97 } 98 99 wantHeader := xrdproto.ResponseHeader{StreamID: xrdproto.StreamID{0}, Status: xrdproto.Ok, DataLength: 8} 100 if !reflect.DeepEqual(wantHeader, respHeader) { 101 t.Errorf("wrong response header:\ngot = %v\nwant = %v", respHeader, wantHeader) 102 } 103 104 want := handshake.Response{ProtocolVersion: 0x310, ServerType: xrdproto.DataServer} 105 if !reflect.DeepEqual(want, handshakeResp) { 106 t.Errorf("wrong handshake response:\ngot = %v\nwant = %v", handshakeResp, want) 107 } 108 109 err = srv.Shutdown(context.Background()) 110 if err != nil { 111 t.Errorf("could not shutdown server: %+v", err) 112 } 113 }() 114 115 if err := srv.Serve(listener); err != nil && err != xrootd.ErrServerClosed { 116 t.Fatalf("unexpected error: %v", err) 117 } 118 } 119 120 func TestServe_Login(t *testing.T) { 121 connsCh := make(chan net.Conn, 1) 122 p1, p2 := net.Pipe() 123 defer p1.Close() 124 defer p2.Close() 125 126 connsCh <- p1 127 listener := &pipeListener{conns: connsCh, close: make(chan struct{})} 128 defer listener.Close() 129 130 srv := xrootd.NewServer(xrootd.Default(), func(err error) { 131 t.Error(err) 132 }) 133 defer func() { 134 _ = srv.Shutdown(context.Background()) 135 }() 136 137 go func() { 138 handshakeReq := handshake.NewRequest() 139 var wBuffer xrdenc.WBuffer 140 err := handshakeReq.MarshalXrd(&wBuffer) 141 if err != nil { 142 t.Errorf("could not marshal handshake request: %+v", err) 143 } 144 _, err = p2.Write(wBuffer.Bytes()) 145 if err != nil { 146 t.Errorf("could not write buffer: %+v", err) 147 } 148 _, _, err = xrdproto.ReadResponse(p2) 149 if err != nil { 150 t.Errorf("unexpected read error: %v", err) 151 } 152 153 req := login.NewRequest("gopher", "") 154 streamID := [2]byte{0, 1} 155 reqHeader := xrdproto.RequestHeader{RequestID: login.RequestID, StreamID: streamID} 156 wBuffer = xrdenc.WBuffer{} 157 err = reqHeader.MarshalXrd(&wBuffer) 158 if err != nil { 159 t.Errorf("could not marshal req-header: %+v", err) 160 } 161 err = req.MarshalXrd(&wBuffer) 162 if err != nil { 163 t.Errorf("could not marshal request: %+v", err) 164 } 165 _, err = p2.Write(wBuffer.Bytes()) 166 if err != nil { 167 t.Errorf("could not write buffer: %+v", err) 168 } 169 respHeader, respData, err := xrdproto.ReadResponse(p2) 170 if err != nil { 171 t.Errorf("unexpected read error: %v", err) 172 } 173 174 var ( 175 loginResp login.Response 176 rBuffer = xrdenc.NewRBuffer(respData) 177 ) 178 179 if err := loginResp.UnmarshalXrd(rBuffer); err != nil { 180 t.Errorf("could not unmarshal: %v", err) 181 } 182 183 wantHeader := xrdproto.ResponseHeader{StreamID: streamID, Status: xrdproto.Ok, DataLength: 16} 184 if !reflect.DeepEqual(wantHeader, respHeader) { 185 t.Errorf("wrong response header:\ngot = %v\nwant = %v", respHeader, wantHeader) 186 } 187 188 // TODO: validate loginResp. 189 190 err = srv.Shutdown(context.Background()) 191 if err != nil { 192 t.Errorf("could not shutdown server: %+v", err) 193 } 194 }() 195 196 if err := srv.Serve(listener); err != nil && err != xrootd.ErrServerClosed { 197 t.Fatalf("unexpected error: %v", err) 198 } 199 } 200 201 func TestServe_Protocol(t *testing.T) { 202 connsCh := make(chan net.Conn, 1) 203 p1, p2 := net.Pipe() 204 defer p1.Close() 205 defer p2.Close() 206 207 connsCh <- p1 208 listener := &pipeListener{conns: connsCh, close: make(chan struct{})} 209 defer listener.Close() 210 211 srv := xrootd.NewServer(xrootd.Default(), func(err error) { 212 t.Error(err) 213 }) 214 defer func() { 215 _ = srv.Shutdown(context.Background()) 216 }() 217 218 go func() { 219 var ( 220 handshakeReq = handshake.NewRequest() 221 wBuffer xrdenc.WBuffer 222 ) 223 err := handshakeReq.MarshalXrd(&wBuffer) 224 if err != nil { 225 t.Errorf("could not marshal handshake request: %+v", err) 226 } 227 _, err = p2.Write(wBuffer.Bytes()) 228 if err != nil { 229 t.Errorf("could not write buffer: %+v", err) 230 } 231 _, _, err = xrdproto.ReadResponse(p2) 232 if err != nil { 233 t.Errorf("unexpected read error: %v", err) 234 } 235 236 req := protocol.NewRequest(0x310, false) 237 streamID := [2]byte{0, 2} 238 reqHeader := xrdproto.RequestHeader{RequestID: protocol.RequestID, StreamID: streamID} 239 wBuffer = xrdenc.WBuffer{} 240 err = reqHeader.MarshalXrd(&wBuffer) 241 if err != nil { 242 t.Errorf("could not marshal request header: %+v", err) 243 } 244 err = req.MarshalXrd(&wBuffer) 245 if err != nil { 246 t.Errorf("could not marshal request: %+v", err) 247 } 248 _, err = p2.Write(wBuffer.Bytes()) 249 if err != nil { 250 t.Errorf("could not write buffer: %+v", err) 251 } 252 253 respHeader, respData, err := xrdproto.ReadResponse(p2) 254 if err != nil { 255 t.Errorf("unexpected read error: %v", err) 256 } 257 258 var ( 259 protocolResp protocol.Response 260 rBuffer = xrdenc.NewRBuffer(respData) 261 ) 262 263 if err := protocolResp.UnmarshalXrd(rBuffer); err != nil { 264 t.Errorf("could not unmarshal: %v", err) 265 } 266 267 wantHeader := xrdproto.ResponseHeader{StreamID: streamID, Status: xrdproto.Ok, DataLength: 8} 268 if !reflect.DeepEqual(wantHeader, respHeader) { 269 t.Errorf("wrong response header:\ngot = %v\nwant = %v", respHeader, wantHeader) 270 } 271 272 want := protocol.Response{BinaryProtocolVersion: 0x310, Flags: protocol.IsServer} 273 if !reflect.DeepEqual(want, protocolResp) { 274 t.Errorf("wrong response:\ngot = %v\nwant = %v", protocolResp, want) 275 } 276 277 err = srv.Shutdown(context.Background()) 278 if err != nil { 279 t.Errorf("could not shutdown server: %+v", err) 280 } 281 }() 282 283 if err := srv.Serve(listener); err != nil && err != xrootd.ErrServerClosed { 284 t.Fatalf("unexpected error: %v", err) 285 } 286 } 287 288 func TestServe_Dirlist(t *testing.T) { 289 connsCh := make(chan net.Conn, 1) 290 p1, p2 := net.Pipe() 291 defer p1.Close() 292 defer p2.Close() 293 294 connsCh <- p1 295 listener := &pipeListener{conns: connsCh, close: make(chan struct{})} 296 defer listener.Close() 297 298 srv := xrootd.NewServer(xrootd.Default(), func(err error) { 299 t.Error(err) 300 }) 301 defer func() { 302 _ = srv.Shutdown(context.Background()) 303 }() 304 305 go func() { 306 var ( 307 handshakeReq = handshake.NewRequest() 308 wBuffer xrdenc.WBuffer 309 ) 310 err := handshakeReq.MarshalXrd(&wBuffer) 311 if err != nil { 312 t.Errorf("could not marshal handshake request: %+v", err) 313 } 314 _, err = p2.Write(wBuffer.Bytes()) 315 if err != nil { 316 t.Errorf("could not write buffer: %+v", err) 317 } 318 _, _, err = xrdproto.ReadResponse(p2) 319 if err != nil { 320 t.Errorf("unexpected read error: %v", err) 321 } 322 323 req := dirlist.NewRequest("/tmp") 324 streamID := [2]byte{0, 2} 325 reqHeader := xrdproto.RequestHeader{RequestID: dirlist.RequestID, StreamID: streamID} 326 wBuffer = xrdenc.WBuffer{} 327 err = reqHeader.MarshalXrd(&wBuffer) 328 if err != nil { 329 t.Errorf("could not marshal request header: %+v", err) 330 } 331 err = req.MarshalXrd(&wBuffer) 332 if err != nil { 333 t.Errorf("could not marshal request: %+v", err) 334 } 335 _, err = p2.Write(wBuffer.Bytes()) 336 if err != nil { 337 t.Errorf("could not write buffer: %+v", err) 338 } 339 340 respHeader, respData, err := xrdproto.ReadResponse(p2) 341 if err != nil { 342 t.Errorf("unexpected read error: %v", err) 343 } 344 345 var ( 346 errorResp xrdproto.ServerError 347 rBuffer = xrdenc.NewRBuffer(respData) 348 ) 349 350 if err := errorResp.UnmarshalXrd(rBuffer); err != nil { 351 t.Errorf("could not unmarshal: %v", err) 352 } 353 354 wantHeader := xrdproto.ResponseHeader{StreamID: streamID, Status: xrdproto.Error, DataLength: 39} 355 if !reflect.DeepEqual(wantHeader, respHeader) { 356 t.Errorf("wrong response header:\ngot = %v\nwant = %v", respHeader, wantHeader) 357 } 358 359 want := xrdproto.ServerError{Code: xrdproto.InvalidRequest, Message: "Dirlist request is not implemented"} 360 if !reflect.DeepEqual(want, errorResp) { 361 t.Errorf("wrong response:\ngot = %v\nwant = %v", errorResp, want) 362 } 363 364 err = srv.Shutdown(context.Background()) 365 if err != nil { 366 t.Errorf("could not shutdown server: %+v", err) 367 } 368 }() 369 370 if err := srv.Serve(listener); err != nil && err != xrootd.ErrServerClosed { 371 t.Fatalf("unexpected error: %v", err) 372 } 373 }