github.com/Cloud-Foundations/Dominator@v0.3.4/objectserver/rpcd/lib/add_test.go (about)

     1  package lib
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  	"net"
     9  	"net/http"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/Cloud-Foundations/Dominator/lib/hash"
    14  	"github.com/Cloud-Foundations/Dominator/lib/log"
    15  	"github.com/Cloud-Foundations/Dominator/lib/log/testlogger"
    16  	oclient "github.com/Cloud-Foundations/Dominator/lib/objectserver/client"
    17  	"github.com/Cloud-Foundations/Dominator/lib/srpc"
    18  )
    19  
    20  var (
    21  	object0 = []byte{0x01, 0x02, 0x03, 0x04}
    22  	object1 = []byte{0x05, 0x06, 0x07}
    23  	object2 = []byte{0x08, 0x09, 0x0a, 0x0b, 0x0c}
    24  )
    25  
    26  type objectsAdder interface {
    27  	AddObjects(*srpc.Conn, srpc.Decoder, srpc.Encoder) error
    28  	Ping(conn *srpc.Conn, request pingRequest, reply *pingResponse) error
    29  }
    30  
    31  type objectAdderType struct {
    32  	failAfter  uint
    33  	numObjects uint
    34  }
    35  
    36  type pingRequest struct {
    37  	Data string
    38  }
    39  
    40  type pingResponse struct {
    41  	Data string
    42  }
    43  
    44  type testReceiverType struct {
    45  	logger      log.Logger
    46  	objectAdder *objectAdderType
    47  }
    48  
    49  func makeObjectsAdderClientAndServer(rcvr objectsAdder) (*srpc.Client, error) {
    50  	listener, err := net.Listen("tcp", "localhost:")
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  	go http.Serve(listener, nil)
    55  	srpc.RegisterName("ObjectServer", rcvr)
    56  	time.Sleep(time.Millisecond)
    57  	stopTime := time.Now().Add(time.Second)
    58  	for ; time.Until(stopTime) > 0; time.Sleep(time.Millisecond) {
    59  		client, err := srpc.DialHTTP("tcp", listener.Addr().String(),
    60  			100*time.Millisecond)
    61  		if err != nil {
    62  			return nil, err
    63  		}
    64  		if err := client.Ping(); err != nil {
    65  			return nil, err
    66  		}
    67  		request := pingRequest{Data: "mydata"}
    68  		var response pingResponse
    69  		err = client.RequestReply("ObjectServer.Ping", request, &response)
    70  		if err != nil {
    71  			return nil, err
    72  		}
    73  		if response.Data != request.Data {
    74  			return nil,
    75  				fmt.Errorf("response.Data: \"%s\" != request.Data: \"%s\"",
    76  					response.Data, request.Data)
    77  		}
    78  		return client, nil
    79  	}
    80  	return nil, errors.New("timed out connecting to server")
    81  }
    82  
    83  func sendObject(t *testing.T, oaQueue *oclient.ObjectAdderQueue,
    84  	object []byte) error {
    85  	time.Sleep(time.Millisecond)
    86  	t.Logf("Sending object with length: %d", len(object))
    87  	_, err := oaQueue.Add(bytes.NewReader(object), uint64(len(object)))
    88  	return err
    89  }
    90  
    91  func TestQueue(t *testing.T) {
    92  	srpcObj := &testReceiverType{
    93  		logger: testlogger.New(t),
    94  		objectAdder: &objectAdderType{
    95  			failAfter: 4,
    96  		},
    97  	}
    98  	srpcClient, err := makeObjectsAdderClientAndServer(srpcObj)
    99  	if err != nil {
   100  		t.Fatal(err)
   101  	}
   102  	oaQueue, err := oclient.NewObjectAdderQueue(srpcClient)
   103  	if err != nil {
   104  		t.Fatal(err)
   105  	}
   106  	if err := sendObject(t, oaQueue, object0); err != nil {
   107  		t.Fatal(err)
   108  	}
   109  	if err := sendObject(t, oaQueue, object1); err != nil {
   110  		t.Fatal(err)
   111  	}
   112  	if err := sendObject(t, oaQueue, object2); err != nil {
   113  		t.Fatal(err)
   114  	}
   115  	if err := oaQueue.Close(); err != nil {
   116  		t.Fatal(err)
   117  	}
   118  	if err := srpcClient.Ping(); err != nil {
   119  		t.Fatalf("Error pinging: %s", err)
   120  	}
   121  	oaQueue, err = oclient.NewObjectAdderQueue(srpcClient)
   122  	if err != nil {
   123  		t.Fatal(err)
   124  	}
   125  	if err := sendObject(t, oaQueue, object0); err != nil {
   126  		t.Fatal(err)
   127  	}
   128  	if err := sendObject(t, oaQueue, object1); err != nil {
   129  		t.Fatal(err)
   130  	}
   131  	if err := sendObject(t, oaQueue, object2); err != nil {
   132  		if err := oaQueue.Close(); err != nil {
   133  			t.Fatal("extra error consumed")
   134  		}
   135  	} else if err := oaQueue.Close(); err == nil {
   136  		t.Fatal("no error consumed")
   137  	}
   138  	if err := srpcClient.Ping(); err != nil {
   139  		t.Fatalf("Error pinging: %s", err)
   140  	}
   141  }
   142  
   143  func (oa *objectAdderType) AddObject(reader io.Reader, length uint64,
   144  	expectedHash *hash.Hash) (hash.Hash, bool, error) {
   145  	if _, err := io.CopyN(io.Discard, reader, int64(length)); err != nil {
   146  		return hash.Hash{}, false, err
   147  	}
   148  	if oa.numObjects >= oa.failAfter {
   149  		return hash.Hash{}, false, errors.New("add error")
   150  	}
   151  	oa.numObjects++
   152  	return *expectedHash, true, nil
   153  }
   154  
   155  func (t *testReceiverType) AddObjects(conn *srpc.Conn, decoder srpc.Decoder,
   156  	encoder srpc.Encoder) error {
   157  	t.logger.Println("Calling AddObjects()")
   158  	return AddObjects(conn, decoder, encoder, t.objectAdder, t.logger)
   159  }
   160  
   161  func (t *testReceiverType) Ping(conn *srpc.Conn,
   162  	request pingRequest, reply *pingResponse) error {
   163  	*reply = pingResponse{Data: request.Data}
   164  	return nil
   165  }