Skip to content

Commit d68febb

Browse files
committed
docs update + tests
1 parent 7415160 commit d68febb

File tree

7 files changed

+215
-11
lines changed

7 files changed

+215
-11
lines changed

CHANGELOG.md

+21
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.
2828
in requests instead of their IDs.
2929
- `GetSchema` function to get the actual schema (#7)
3030
- Support connection via an existing socket fd (#321)
31+
- Ability to mock connections for tests (#237). Added new structs `MockDoer`,
32+
`MockRequest`.
33+
- `CreateResponse` method added to the `Request` interface (#237)
34+
- `Header` struct for the response header (#237). It can be accessed via
35+
`Header()` method of the `Response` interface.
3136

3237
### Changed
3338

@@ -67,6 +72,22 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.
6772
it (#321)
6873
- Rename `pool.GetPoolInfo` to `pool.GetInfo`. Change return type to
6974
`map[string]ConnectionInfo` (#321)
75+
- All responses are now implementations of an `Response` interface (#237).
76+
`SelectResponse`, `ExecuteResponse`, `PrepareResponse`, `PushResponse` are part
77+
of a public API. `Pos()`, `MetaData()`, `SQLInfo()` methods created for them
78+
to get specific info.
79+
- `IsPush()` method is added to the response iterator (#237). It returns
80+
the information if the current response a `PushResponse`.
81+
`PushCode` constant is removed.
82+
- `Future` constructors now accept `Request` as their argument (#237).
83+
Method `Get` now returns response data. To get the actual response new method
84+
added `GetResponse`. Methods `AppendPush` and `SetResponse` accepts
85+
response `Header` and data as their arguments.
86+
- All deprecated requests operations on a `Connector` return response data
87+
instead of an actual responses (#237)
88+
- Renamed `StrangerResponse` to `MockResponse` (#237)
89+
- `GetSchema` now accepts a `Doer` as an argument (instead of the
90+
`Connection`) (#237)
7091

7192
### Deprecated
7293

README.md

+46-3
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,10 @@ func main() {
130130
}
131131
resp, err := conn.Do(tarantool.NewInsertRequest(999).
132132
Tuple([]interface{}{99999, "BB"}),
133-
).Get()
133+
).GetResponse()
134134
if err != nil {
135135
fmt.Println("Error", err)
136-
fmt.Println("Code", resp.Code)
136+
fmt.Println("Code", resp.Header().Code)
137137
}
138138
}
139139
```
@@ -201,12 +201,18 @@ The subpackage has been deleted. You could use `pool` instead.
201201
unique string ID, which allows them to be distinguished.
202202
* `pool.GetPoolInfo` has been renamed to `pool.GetInfo`. Return type has been changed
203203
to `map[string]ConnectionInfo`.
204+
* All deprecated requests operations on a `Pooler` return response data
205+
instead of an actual responses.
204206

205207
#### crud package
206208

207209
* `crud` operations `Timeout` option has `crud.OptFloat64` type
208210
instead of `crud.OptUint`.
209211

212+
#### test_helpers package
213+
214+
Renamed `StrangerResponse` to `MockResponse`.
215+
210216
#### msgpack.v5
211217

212218
Most function names and argument types in `msgpack.v5` and `msgpack.v2`
@@ -241,7 +247,10 @@ of the requests is an array instead of array of arrays.
241247

242248
#### IPROTO constants
243249

244-
IPROTO constants have been moved to a separate package [go-iproto](https://github.com/tarantool/go-iproto).
250+
* IPROTO constants have been moved to a separate package [go-iproto](https://github.com/tarantool/go-iproto).
251+
* `PushCode` constant is removed. To get information, if the current response is
252+
a push response, new `IsPush()` method of the response iterator could be used
253+
instead.
245254

246255
#### Request changes
247256

@@ -254,6 +263,36 @@ longer accept `ops` argument (operations) as an `interface{}`. `*Operations`
254263
needs to be passed instead.
255264
* `UpdateRequest` and `UpsertRequest` structs no longer accept `interface{}`
256265
for an `ops` field. `*Operations` needs to be used instead.
266+
* `CreateResponse` method added to the `Request` interface.
267+
268+
#### Response changes
269+
270+
* New interface `Response` added.
271+
* For each request, a different response struct is created. They all implement a
272+
`Response` interface. `SelectResponse`, `PrepareResponse`, `ExecuteResponse`,
273+
`PushResponse` are a part of a public API. `Pos()`, `MetaData()`, `SQLInfo()`
274+
methods created for them to get specific info.
275+
* Response header stored in a new `Header` struct. It could be accessed via
276+
`Header()` method.
277+
278+
#### Response iterator changes
279+
280+
Method `IsPush()` is added to the `ResponseIterator` interface.
281+
It returns true if the current response is a push response.
282+
283+
#### Future changes
284+
285+
* `Future` constructors now accept `Request` as their argument.
286+
* Method `Get` now returns response data instead of the actual response.
287+
* New method `GetResponse` added to get an actual response.
288+
* Methods `AppendPush` and `SetResponse` accepts response `Header` and data
289+
as their arguments.
290+
291+
#### Connector changes
292+
293+
* All deprecated requests operations on a `Connector` return response data
294+
instead of an actual responses.
295+
* New interface `Doer` is added as a child-interface instead of a `Do` method.
257296

258297
#### Connect function
259298

@@ -267,6 +306,10 @@ If you were using a non-SSL connection, you need to create `NetDialer`.
267306
For SSL-enabled connections, use `OpenSslDialer`. Please note that the options
268307
for creating a connection are now stored in corresponding `Dialer`, not in `Opts`.
269308

309+
#### GetSchema function
310+
311+
`GetSchema` now accepts a `Doer` as an argument.
312+
270313
#### Connection schema
271314

272315
* Removed `Schema` field from the `Connection` struct. Instead, new

example_test.go

+59-2
Original file line numberDiff line numberDiff line change
@@ -198,16 +198,32 @@ func ExampleSelectRequest() {
198198
}
199199

200200
key := []interface{}{uint(1111)}
201-
data, err := conn.Do(tarantool.NewSelectRequest(617).
201+
resp, err := conn.Do(tarantool.NewSelectRequest(617).
202202
Limit(100).
203203
Iterator(tarantool.IterEq).
204204
Key(key),
205-
).Get()
205+
).GetResponse()
206206

207207
if err != nil {
208208
fmt.Printf("error in select is %v", err)
209209
return
210210
}
211+
selResp, ok := resp.(*tarantool.SelectResponse)
212+
if !ok {
213+
fmt.Print("wrong response type")
214+
return
215+
}
216+
pos, err := selResp.Pos()
217+
if err != nil {
218+
fmt.Printf("error in Pos: %v", err)
219+
return
220+
}
221+
fmt.Printf("pos for Select is %v\n", pos)
222+
data, err := resp.Decode()
223+
if err != nil {
224+
fmt.Printf("error while decoding: %v", err)
225+
return
226+
}
211227
fmt.Printf("response is %#v\n", data)
212228

213229
var res []Tuple
@@ -224,6 +240,7 @@ func ExampleSelectRequest() {
224240
fmt.Printf("response is %v\n", res)
225241

226242
// Output:
243+
// pos for Select is []
227244
// response is []interface {}{[]interface {}{0x457, "hello", "world"}}
228245
// response is [{{} 1111 hello world}]
229246
}
@@ -747,6 +764,46 @@ func ExampleExecuteRequest() {
747764
fmt.Println("Error", err)
748765
}
749766

767+
func ExamplePrepareRequest() {
768+
conn := exampleConnect(dialer, opts)
769+
defer conn.Close()
770+
771+
resp, err := conn.Do(
772+
tarantool.NewPrepareRequest("SELECT NULL WHERE FALSE;"),
773+
).GetResponse()
774+
775+
if err != nil {
776+
fmt.Printf("error in prepare is %v", err)
777+
return
778+
}
779+
prepResp, ok := resp.(*tarantool.PrepareResponse)
780+
if !ok {
781+
fmt.Print("wrong response type")
782+
return
783+
}
784+
metaData, err := prepResp.MetaData()
785+
if err != nil {
786+
fmt.Printf("error in MetaData: %v", err)
787+
return
788+
}
789+
fmt.Printf("metaData for Prepare is %v\n", metaData)
790+
sqlInfo, err := prepResp.SQLInfo()
791+
if err != nil {
792+
fmt.Printf("error in SQLInfo: %v", err)
793+
return
794+
}
795+
fmt.Printf("sqlInfo for Prepare is %v\n", sqlInfo)
796+
_, err = resp.Decode()
797+
if err != nil {
798+
fmt.Printf("error while decoding: %v", err)
799+
return
800+
}
801+
802+
// Output:
803+
// metaData for Prepare is [{COLUMN_1 scalar false false }]
804+
// sqlInfo for Prepare is {0 []}
805+
}
806+
750807
func getTestTxnDialer() tarantool.Dialer {
751808
txnDialer := dialer
752809

future.go

-5
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,6 @@ func (fut *Future) AppendPush(header Header, body io.Reader) error {
158158
return nil
159159
}
160160

161-
// SetRequest sets a request, for which the future was created.
162-
func (fut *Future) SetRequest(req Request) {
163-
fut.req = req
164-
}
165-
166161
// SetResponse sets a response for the future and finishes the future.
167162
func (fut *Future) SetResponse(header Header, body io.Reader) error {
168163
fut.mutex.Lock()

future_test.go

+41-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package tarantool_test
22

33
import (
4+
"bytes"
45
"errors"
56
"sync"
67
"testing"
@@ -126,7 +127,6 @@ func TestFutureGetIteratorResponseOnTimeout(t *testing.T) {
126127

127128
wait.Wait()
128129

129-
fut.SetRequest(test_helpers.NewMockRequest())
130130
fut.SetResponse(respHeader, nil)
131131
done.Wait()
132132
}
@@ -259,3 +259,43 @@ func TestFutureSetStateRaceCondition(t *testing.T) {
259259
// It may be false-positive, but very rarely - it's ok for such very
260260
// simple race conditions tests.
261261
}
262+
263+
func TestFutureGetIteratorIsPush(t *testing.T) {
264+
fut := NewFuture(test_helpers.NewMockRequest())
265+
fut.AppendPush(Header{}, nil)
266+
fut.SetResponse(Header{}, nil)
267+
it := fut.GetIterator()
268+
269+
assert.True(t, it.IsPush())
270+
it.Next()
271+
assert.False(t, it.IsPush())
272+
}
273+
274+
func TestFuture_Get(t *testing.T) {
275+
resp := test_helpers.NewMockResponse(t, []interface{}{'v', '2'})
276+
277+
fut := NewFuture(test_helpers.NewMockRequest())
278+
fut.SetResponse(Header{}, bytes.NewBuffer(resp.GetData()))
279+
280+
data, err := fut.Get()
281+
assert.NoError(t, err)
282+
assert.Equal(t, 2, len(data))
283+
assert.Equal(t, 'v', data[0])
284+
assert.Equal(t, '2', data[1])
285+
}
286+
287+
func TestFuture_GetResponse(t *testing.T) {
288+
mockResp := test_helpers.NewMockResponse(t, []interface{}{'v', '2'})
289+
290+
fut := NewFuture(test_helpers.NewMockRequest())
291+
fut.SetResponse(Header{}, bytes.NewBuffer(mockResp.GetData()))
292+
293+
resp, err := fut.GetResponse()
294+
assert.NoError(t, err)
295+
296+
data, err := resp.Decode()
297+
assert.NoError(t, err)
298+
assert.Equal(t, 2, len(data))
299+
assert.Equal(t, 'v', data[0])
300+
assert.Equal(t, '2', data[1])
301+
}

request_test.go

+43
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"context"
66
"errors"
7+
"fmt"
78
"testing"
89
"time"
910

@@ -1007,3 +1008,45 @@ func TestWatchOnceRequestDefaultValues(t *testing.T) {
10071008
req := NewWatchOnceRequest(validKey)
10081009
assertBodyEqual(t, refBuf.Bytes(), req)
10091010
}
1011+
1012+
func TestCreateResponse(t *testing.T) {
1013+
header := Header{}
1014+
data := bytes.NewBuffer([]byte{'v', '2'})
1015+
baseExample, err := NewPingRequest().CreateResponse(header, data)
1016+
assert.NoError(t, err)
1017+
1018+
tests := []struct {
1019+
req Request
1020+
expected Response
1021+
}{
1022+
{req: NewSelectRequest(validSpace), expected: &SelectResponse{}},
1023+
{req: NewUpdateRequest(validSpace), expected: baseExample},
1024+
{req: NewUpsertRequest(validSpace), expected: baseExample},
1025+
{req: NewInsertRequest(validSpace), expected: baseExample},
1026+
{req: NewReplaceRequest(validSpace), expected: baseExample},
1027+
{req: NewDeleteRequest(validSpace), expected: baseExample},
1028+
{req: NewCallRequest(validExpr), expected: baseExample},
1029+
{req: NewCall16Request(validExpr), expected: baseExample},
1030+
{req: NewCall17Request(validExpr), expected: baseExample},
1031+
{req: NewEvalRequest(validExpr), expected: baseExample},
1032+
{req: NewExecuteRequest(validExpr), expected: &ExecuteResponse{}},
1033+
{req: NewPingRequest(), expected: baseExample},
1034+
{req: NewPrepareRequest(validExpr), expected: &PrepareResponse{}},
1035+
{req: NewUnprepareRequest(validStmt), expected: baseExample},
1036+
{req: NewExecutePreparedRequest(validStmt), expected: &ExecuteResponse{}},
1037+
{req: NewBeginRequest(), expected: baseExample},
1038+
{req: NewCommitRequest(), expected: baseExample},
1039+
{req: NewRollbackRequest(), expected: baseExample},
1040+
{req: NewIdRequest(validProtocolInfo), expected: baseExample},
1041+
{req: NewBroadcastRequest(validKey), expected: baseExample},
1042+
{req: NewWatchOnceRequest(validKey), expected: baseExample},
1043+
}
1044+
1045+
for _, test := range tests {
1046+
resp, err := test.req.CreateResponse(header, data)
1047+
assert.NoError(t, err)
1048+
assert.True(t, fmt.Sprintf("%T", resp) ==
1049+
fmt.Sprintf("%T", test.expected))
1050+
assert.Equal(t, header, resp.Header())
1051+
}
1052+
}

test_helpers/response.go

+5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ type MockResponse struct {
1919
data []byte
2020
}
2121

22+
// GetData is a getter for a data field.
23+
func (resp *MockResponse) GetData() []byte {
24+
return resp.data
25+
}
26+
2227
// NewMockResponse creates a new MockResponse with an empty header and the given data.
2328
// body should be passed as a structure to be encoded.
2429
// The encoded body is served as response data and will be decoded once the

0 commit comments

Comments
 (0)