go-hep.org/x/hep@v0.38.1/xrootd/file_mock_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 // import "go-hep.org/x/hep/xrootd"
     6  
     7  import (
     8  	"context"
     9  	"encoding/binary"
    10  	"hash/crc32"
    11  	"net"
    12  	"reflect"
    13  	"testing"
    14  
    15  	"go-hep.org/x/hep/xrootd/xrdfs"
    16  	"go-hep.org/x/hep/xrootd/xrdproto"
    17  	"go-hep.org/x/hep/xrootd/xrdproto/read"
    18  	"go-hep.org/x/hep/xrootd/xrdproto/stat"
    19  	"go-hep.org/x/hep/xrootd/xrdproto/sync"
    20  	"go-hep.org/x/hep/xrootd/xrdproto/truncate"
    21  	"go-hep.org/x/hep/xrootd/xrdproto/verifyw"
    22  	"go-hep.org/x/hep/xrootd/xrdproto/write"
    23  	"go-hep.org/x/hep/xrootd/xrdproto/xrdclose"
    24  )
    25  
    26  func TestFile_Close_Mock(t *testing.T) {
    27  	t.Parallel()
    28  
    29  	handle := xrdfs.FileHandle{1, 2, 3, 4}
    30  	wantRequest := xrdclose.Request{Handle: handle}
    31  
    32  	serverFunc := func(cancel func(), conn net.Conn) {
    33  		data, err := xrdproto.ReadRequest(conn)
    34  		if err != nil {
    35  			cancel()
    36  			t.Fatalf("could not read request: %v", err)
    37  		}
    38  
    39  		var gotRequest xrdclose.Request
    40  		gotHeader, err := unmarshalRequest(data, &gotRequest)
    41  		if err != nil {
    42  			cancel()
    43  			t.Fatalf("could not unmarshal request: %v", err)
    44  		}
    45  
    46  		if !reflect.DeepEqual(gotRequest, wantRequest) {
    47  			cancel()
    48  			t.Fatalf("request info does not match:\ngot = %v\nwant = %v", gotRequest, wantRequest)
    49  		}
    50  
    51  		err = xrdproto.WriteResponse(conn, gotHeader.StreamID, xrdproto.Ok, nil)
    52  		if err != nil {
    53  			cancel()
    54  			t.Fatalf("could not write response: %v", err)
    55  		}
    56  	}
    57  
    58  	clientFunc := func(cancel func(), client *Client) {
    59  		file := file{fs: client.FS().(*fileSystem), handle: handle, sessionID: client.initialSessionID}
    60  
    61  		err := file.Close(context.Background())
    62  		if err != nil {
    63  			t.Fatalf("invalid close call: %v", err)
    64  		}
    65  	}
    66  
    67  	testClientWithMockServer(serverFunc, clientFunc)
    68  }
    69  
    70  func TestFile_Sync_Mock(t *testing.T) {
    71  	t.Parallel()
    72  
    73  	handle := xrdfs.FileHandle{1, 2, 3, 4}
    74  	wantRequest := sync.Request{Handle: handle}
    75  
    76  	serverFunc := func(cancel func(), conn net.Conn) {
    77  		data, err := xrdproto.ReadRequest(conn)
    78  		if err != nil {
    79  			cancel()
    80  			t.Fatalf("could not read request: %v", err)
    81  		}
    82  
    83  		var gotRequest sync.Request
    84  		gotHeader, err := unmarshalRequest(data, &gotRequest)
    85  		if err != nil {
    86  			cancel()
    87  			t.Fatalf("could not unmarshal request: %v", err)
    88  		}
    89  
    90  		if !reflect.DeepEqual(gotRequest, wantRequest) {
    91  			cancel()
    92  			t.Fatalf("request info does not match:\ngot = %v\nwant = %v", gotRequest, wantRequest)
    93  		}
    94  
    95  		err = xrdproto.WriteResponse(conn, gotHeader.StreamID, xrdproto.Ok, nil)
    96  		if err != nil {
    97  			cancel()
    98  			t.Fatalf("could not write response: %v", err)
    99  		}
   100  	}
   101  
   102  	clientFunc := func(cancel func(), client *Client) {
   103  		file := file{fs: client.FS().(*fileSystem), handle: handle, sessionID: client.initialSessionID}
   104  
   105  		err := file.Sync(context.Background())
   106  		if err != nil {
   107  			t.Fatalf("invalid sync call: %v", err)
   108  		}
   109  	}
   110  
   111  	testClientWithMockServer(serverFunc, clientFunc)
   112  }
   113  
   114  func TestFile_ReadAt_Mock(t *testing.T) {
   115  	t.Parallel()
   116  
   117  	handle := xrdfs.FileHandle{1, 2, 3, 4}
   118  	want := []byte("Hello XRootD.\n")
   119  	askLength := int32(len(want) + 4)
   120  
   121  	wantRequest := read.Request{Handle: handle, Offset: 1, Length: askLength, OptionalArgs: &read.OptionalArgs{PathID: 0}}
   122  
   123  	serverFunc := func(cancel func(), conn net.Conn) {
   124  		data, err := xrdproto.ReadRequest(conn)
   125  		if err != nil {
   126  			cancel()
   127  			t.Fatalf("could not read request: %v", err)
   128  		}
   129  
   130  		var gotRequest read.Request
   131  		gotHeader, err := unmarshalRequest(data, &gotRequest)
   132  		if err != nil {
   133  			cancel()
   134  			t.Fatalf("could not unmarshal request: %v", err)
   135  		}
   136  
   137  		if !reflect.DeepEqual(*gotRequest.OptionalArgs, *wantRequest.OptionalArgs) {
   138  			cancel()
   139  			t.Fatalf("optional args do not match:\ngot = %v\nwant = %v", *gotRequest.OptionalArgs, *wantRequest.OptionalArgs)
   140  		}
   141  
   142  		gotRequest.OptionalArgs = nil
   143  		wantRequest.OptionalArgs = nil
   144  
   145  		if !reflect.DeepEqual(gotRequest, wantRequest) {
   146  			cancel()
   147  			t.Fatalf("request info does not match:\ngot = %v\nwant = %v", gotRequest, wantRequest)
   148  		}
   149  
   150  		err = xrdproto.WriteResponse(conn, gotHeader.StreamID, xrdproto.OkSoFar, read.Response{Data: want[:5]})
   151  		if err != nil {
   152  			cancel()
   153  			t.Fatalf("could not write response: %v", err)
   154  		}
   155  
   156  		err = xrdproto.WriteResponse(conn, gotHeader.StreamID, xrdproto.Ok, read.Response{Data: want[5:]})
   157  		if err != nil {
   158  			cancel()
   159  			t.Fatalf("could not write response: %v", err)
   160  		}
   161  	}
   162  
   163  	clientFunc := func(cancel func(), client *Client) {
   164  		file := file{fs: client.FS().(*fileSystem), handle: handle, sessionID: client.initialSessionID}
   165  		got := make([]uint8, askLength)
   166  
   167  		n, err := file.ReadAt(got, 1)
   168  		if err != nil {
   169  			t.Fatalf("invalid read call: %v", err)
   170  		}
   171  		if n != len(want) {
   172  			t.Fatalf("read count does not match:\ngot = %v\nwant = %v", n, len(want))
   173  		}
   174  
   175  		if !reflect.DeepEqual(got[:n], want) {
   176  			t.Fatalf("read data does not match:\ngot = %v\nwant = %v", got[:n], want)
   177  		}
   178  	}
   179  
   180  	testClientWithMockServer(serverFunc, clientFunc)
   181  }
   182  
   183  func TestFile_WriteAt_Mock(t *testing.T) {
   184  	t.Parallel()
   185  
   186  	handle := xrdfs.FileHandle{1, 2, 3, 4}
   187  	want := []byte("Hello XRootD.\n")
   188  
   189  	wantRequest := write.Request{Handle: handle, Offset: 1, Data: want}
   190  
   191  	serverFunc := func(cancel func(), conn net.Conn) {
   192  		data, err := xrdproto.ReadRequest(conn)
   193  		if err != nil {
   194  			cancel()
   195  			t.Fatalf("could not read request: %v", err)
   196  		}
   197  
   198  		var gotRequest write.Request
   199  		gotHeader, err := unmarshalRequest(data, &gotRequest)
   200  		if err != nil {
   201  			cancel()
   202  			t.Fatalf("could not unmarshal request: %v", err)
   203  		}
   204  
   205  		if !reflect.DeepEqual(gotRequest, wantRequest) {
   206  			cancel()
   207  			t.Fatalf("request info does not match:\ngot = %v\nwant = %v", gotRequest, wantRequest)
   208  		}
   209  
   210  		err = xrdproto.WriteResponse(conn, gotHeader.StreamID, xrdproto.Ok, nil)
   211  		if err != nil {
   212  			cancel()
   213  			t.Fatalf("could not write response: %v", err)
   214  		}
   215  	}
   216  
   217  	clientFunc := func(cancel func(), client *Client) {
   218  		file := file{fs: client.FS().(*fileSystem), handle: handle, sessionID: client.initialSessionID}
   219  
   220  		n, err := file.WriteAt(want, 1)
   221  		if err != nil {
   222  			t.Fatalf("invalid write call: %v", err)
   223  		}
   224  		if n != len(want) {
   225  			t.Fatalf("write count does not match:\ngot = %v\nwant = %v", n, len(want))
   226  		}
   227  	}
   228  
   229  	testClientWithMockServer(serverFunc, clientFunc)
   230  }
   231  
   232  func TestFile_Truncate_Mock(t *testing.T) {
   233  	t.Parallel()
   234  
   235  	var (
   236  		handle         = xrdfs.FileHandle{1, 2, 3, 4}
   237  		wantSize int64 = 10
   238  	)
   239  
   240  	wantRequest := truncate.Request{Handle: handle, Size: wantSize}
   241  
   242  	serverFunc := func(cancel func(), conn net.Conn) {
   243  		data, err := xrdproto.ReadRequest(conn)
   244  		if err != nil {
   245  			cancel()
   246  			t.Fatalf("could not read request: %v", err)
   247  		}
   248  
   249  		var gotRequest truncate.Request
   250  		gotHeader, err := unmarshalRequest(data, &gotRequest)
   251  		if err != nil {
   252  			cancel()
   253  			t.Fatalf("could not unmarshal request: %v", err)
   254  		}
   255  
   256  		if !reflect.DeepEqual(gotRequest, wantRequest) {
   257  			cancel()
   258  			t.Fatalf("request info does not match:\ngot = %v\nwant = %v", gotRequest, wantRequest)
   259  		}
   260  
   261  		err = xrdproto.WriteResponse(conn, gotHeader.StreamID, xrdproto.Ok, nil)
   262  		if err != nil {
   263  			cancel()
   264  			t.Fatalf("could not write response: %v", err)
   265  		}
   266  	}
   267  
   268  	clientFunc := func(cancel func(), client *Client) {
   269  		file := file{fs: client.FS().(*fileSystem), handle: handle, sessionID: client.initialSessionID}
   270  
   271  		err := file.Truncate(context.Background(), wantSize)
   272  		if err != nil {
   273  			t.Fatalf("invalid truncate call: %v", err)
   274  		}
   275  	}
   276  
   277  	testClientWithMockServer(serverFunc, clientFunc)
   278  }
   279  
   280  func TestFile_Stat_Mock(t *testing.T) {
   281  	t.Parallel()
   282  
   283  	handle := xrdfs.FileHandle{0, 1, 2, 3}
   284  
   285  	var want = &xrdfs.EntryStat{
   286  		EntrySize:   20,
   287  		Mtime:       10,
   288  		HasStatInfo: true,
   289  	}
   290  
   291  	var wantRequest = stat.Request{FileHandle: handle}
   292  
   293  	serverFunc := func(cancel func(), conn net.Conn) {
   294  		data, err := xrdproto.ReadRequest(conn)
   295  		if err != nil {
   296  			cancel()
   297  			t.Fatalf("could not read request: %v", err)
   298  		}
   299  
   300  		var gotRequest stat.Request
   301  		gotHeader, err := unmarshalRequest(data, &gotRequest)
   302  		if err != nil {
   303  			cancel()
   304  			t.Fatalf("could not unmarshal request: %v", err)
   305  		}
   306  
   307  		if !reflect.DeepEqual(gotRequest, wantRequest) {
   308  			cancel()
   309  			t.Fatalf("request info does not match:\ngot = %v\nwant = %v", gotRequest, wantRequest)
   310  		}
   311  
   312  		err = xrdproto.WriteResponse(conn, gotHeader.StreamID, xrdproto.Ok, stat.DefaultResponse{EntryStat: *want})
   313  		if err != nil {
   314  			cancel()
   315  			t.Fatalf("could not write response: %v", err)
   316  		}
   317  	}
   318  
   319  	clientFunc := func(cancel func(), client *Client) {
   320  		var fs = client.FS().(*fileSystem)
   321  		file := file{fs: fs, handle: handle, sessionID: client.initialSessionID}
   322  		got, err := file.Stat(context.Background())
   323  		if err != nil {
   324  			t.Fatalf("invalid stat call: %v", err)
   325  		}
   326  		if !reflect.DeepEqual(&got, want) {
   327  			t.Fatalf("stat info does not match:\ngot = %v\nwant = %v", &got, want)
   328  		}
   329  		if !reflect.DeepEqual(file.Info(), want) {
   330  			t.Fatalf("stat info does not match:\nfile.Info() = %v\nwant = %v", file.Info(), want)
   331  		}
   332  	}
   333  
   334  	testClientWithMockServer(serverFunc, clientFunc)
   335  }
   336  
   337  func TestFile_VerifyWriteAt_Mock(t *testing.T) {
   338  	t.Parallel()
   339  
   340  	handle := xrdfs.FileHandle{1, 2, 3, 4}
   341  	data := []byte("Hello XRootD.\n")
   342  	crc := crc32.ChecksumIEEE(data)
   343  	crcData := make([]uint8, 4, 4+len(data))
   344  	binary.BigEndian.PutUint32(crcData, crc)
   345  	crcData = append(crcData, data...)
   346  
   347  	wantRequest := verifyw.Request{Handle: handle, Offset: 1, Data: crcData, Verification: verifyw.CRC32}
   348  
   349  	serverFunc := func(cancel func(), conn net.Conn) {
   350  		data, err := xrdproto.ReadRequest(conn)
   351  		if err != nil {
   352  			cancel()
   353  			t.Fatalf("could not read request: %v", err)
   354  		}
   355  
   356  		var gotRequest verifyw.Request
   357  		gotHeader, err := unmarshalRequest(data, &gotRequest)
   358  		if err != nil {
   359  			cancel()
   360  			t.Fatalf("could not unmarshal request: %v", err)
   361  		}
   362  
   363  		if !reflect.DeepEqual(gotRequest, wantRequest) {
   364  			cancel()
   365  			t.Fatalf("request info does not match:\ngot = %v\nwant = %v", gotRequest, wantRequest)
   366  		}
   367  
   368  		err = xrdproto.WriteResponse(conn, gotHeader.StreamID, xrdproto.Ok, nil)
   369  		if err != nil {
   370  			cancel()
   371  			t.Fatalf("could not write response: %v", err)
   372  		}
   373  	}
   374  
   375  	clientFunc := func(cancel func(), client *Client) {
   376  		file := file{fs: client.FS().(*fileSystem), handle: handle, sessionID: client.initialSessionID}
   377  
   378  		err := file.VerifyWriteAt(context.Background(), data, 1)
   379  		if err != nil {
   380  			t.Fatalf("invalid verifyw call: %v", err)
   381  		}
   382  	}
   383  
   384  	testClientWithMockServer(serverFunc, clientFunc)
   385  }