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 }