Skip to content

Commit fc70848

Browse files
committed
temporary commit
* preemptive checking for empty connection * hide constructors for schema and etc * redo (minify) API for box.session.su (simplify it) * added mock tests to check API
1 parent 26f10c6 commit fc70848

File tree

9 files changed

+101
-66
lines changed

9 files changed

+101
-66
lines changed

box/box.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ type Box struct {
1212

1313
// New returns a new instance of the box structure, which implements the Box interface.
1414
func New(conn tarantool.Doer) *Box {
15+
if conn == nil {
16+
// Check if the provided Tarantool connection is nil, and if it is, panic with an error message.
17+
// panic early helps to catch and fix nil pointer issues in the code.
18+
panic("tarantool connection cannot be nil")
19+
}
20+
1521
return &Box{
1622
conn: conn, // Assigns the provided Tarantool connection.
1723
}
@@ -20,7 +26,7 @@ func New(conn tarantool.Doer) *Box {
2026
// Schema returns a new Schema instance, providing access to schema-related operations.
2127
// It uses the connection from the Box instance to communicate with Tarantool.
2228
func (b *Box) Schema() *Schema {
23-
return NewSchema(b.conn)
29+
return newSchema(b.conn)
2430
}
2531

2632
// Info retrieves the current information of the Tarantool instance.

box/box_test.go

Lines changed: 64 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,86 @@
1-
package box
1+
package box_test
22

33
import (
4+
"context"
5+
"errors"
46
"testing"
57

68
"github.com/stretchr/testify/assert"
79
"github.com/stretchr/testify/require"
8-
10+
"github.com/tarantool/go-tarantool/v2/box"
911
"github.com/tarantool/go-tarantool/v2/test_helpers"
1012
)
1113

1214
func TestNew(t *testing.T) {
1315
t.Parallel()
1416

15-
// Create a box instance with a nil connection. This should lead to a panic later.
16-
b := New(nil)
17+
// Create a box instance with a nil connection. This should lead to a panic.
18+
require.Panics(t, func() { box.New(nil) })
19+
}
20+
21+
func TestMocked(t *testing.T) {
22+
t.Run("Box.Info", func(t *testing.T) {
23+
t.Parallel()
1724

18-
// Ensure the box instance is not nil (which it shouldn't be), but this is not meaningful
19-
// since we will panic when we call the Info method with the nil connection.
20-
require.NotNil(t, b)
25+
data := []interface{}{
26+
map[string]interface{}{
27+
"version": "1.0.0",
28+
"id": nil,
29+
"ro": false,
30+
"uuid": "uuid",
31+
"pid": 456,
32+
"status": "status",
33+
"lsn": 123,
34+
"replication": nil,
35+
},
36+
}
37+
mock := test_helpers.NewMockDoer(t,
38+
test_helpers.NewMockResponse(t, data),
39+
)
40+
b := box.New(&mock)
2141

22-
// We expect a panic because we are passing a nil connection (nil Doer) to the By function.
23-
// The library does not control this zone, and the nil connection would cause a runtime error
24-
// when we attempt to call methods (like Info) on it.
25-
// This test ensures that such an invalid state is correctly handled by causing a panic,
26-
// as it's outside the library's responsibility.
27-
require.Panics(t, func() {
42+
info, err := b.Info()
43+
require.NoError(t, err)
2844

29-
// Calling Info on a box with a nil connection will result in a panic, since the underlying
30-
// connection (Doer) cannot perform the requested action (it's nil).
31-
_, _ = b.Info()
45+
assert.Equal(t, "1.0.0", info.Version)
46+
assert.Equal(t, 456, info.PID)
3247
})
33-
}
3448

35-
func TestNew_Schema_PassesDoer(t *testing.T) {
36-
t.Parallel()
49+
t.Run("Box.Schema.User.Info", func(t *testing.T) {
50+
t.Parallel()
3751

38-
doer := test_helpers.NewMockDoer(t)
52+
data := []interface{}{
53+
[]interface{}{
54+
[]interface{}{"read,write,execute", "universe", ""},
55+
},
56+
}
57+
mock := test_helpers.NewMockDoer(t,
58+
test_helpers.NewMockResponse(t, data),
59+
)
60+
b := box.New(&mock)
3961

40-
b := New(&doer)
41-
schemaObject := b.Schema()
42-
assert.Equal(t, &doer, schemaObject.conn)
62+
privs, err := b.Schema().User().Info(context.Background(), "username")
63+
require.NoError(t, err)
4364

44-
userSchemaObject := b.Schema().User()
45-
assert.Equal(t, &doer, userSchemaObject.conn)
65+
assert.Equal(t, []box.Privilege{
66+
{
67+
Permissions: []box.Permission{box.PermissionRead, box.PermissionWrite, box.PermissionExecute},
68+
Type: box.PrivilegeUniverse,
69+
Name: "",
70+
},
71+
}, privs)
72+
})
73+
74+
t.Run("Box.Session.Su", func(t *testing.T) {
75+
t.Parallel()
4676

47-
sessionObject := b.Session()
48-
assert.Equal(t, &doer, sessionObject.conn)
77+
mock := test_helpers.NewMockDoer(t,
78+
test_helpers.NewMockResponse(t, []interface{}{}),
79+
errors.New("user not found or supplied credentials are invalid"),
80+
)
81+
b := box.New(&mock)
82+
83+
err := b.Session().Su(context.Background(), "admin")
84+
require.NoError(t, err)
85+
})
4986
}

box/schema.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ type Schema struct {
88
conn tarantool.Doer // Connection interface for interacting with Tarantool.
99
}
1010

11-
// NewSchema creates a new Schema instance with the provided Tarantool connection.
11+
// newSchema creates a new Schema instance with the provided Tarantool connection.
1212
// It initializes a Schema object that can be used for schema-related operations
1313
// such as managing users, tables, and other schema elements in the Tarantool instance.
14-
func NewSchema(conn tarantool.Doer) *Schema {
14+
func newSchema(conn tarantool.Doer) *Schema {
1515
return &Schema{conn: conn} // Pass the connection to the Schema.
1616
}
1717

box/schema_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
)
1111

1212
func TestSchemaNotNil(t *testing.T) {
13-
b := NewSchema(nil)
13+
b := newSchema(nil)
1414
require.NotNil(t, b)
1515
require.NotNil(t, b.User())
1616
}
@@ -23,15 +23,15 @@ func TestSchemaConnectionsEquality(t *testing.T) {
2323
}
2424

2525
for _, tCase := range tCases {
26-
sch := NewSchema(tCase)
26+
sch := newSchema(tCase)
2727
require.Equal(t, tCase, sch.conn)
2828
require.Equal(t, tCase, sch.User().conn)
2929
}
3030
}
3131

3232
func TestSchemaNilConnectionPanics(t *testing.T) {
3333
ctx := context.Background()
34-
b := NewSchema(nil)
34+
b := newSchema(nil)
3535

3636
require.Panics(t, func() {
3737
_, _ = b.User().Info(ctx, "panic-on")

box/schema_user.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,8 +378,11 @@ func (uer *UserInfoResponse) DecodeMsgpack(d *msgpack.Decoder) error {
378378
rawArr := make([][][3]string, 0)
379379

380380
err := d.Decode(&rawArr)
381-
if err != nil {
381+
switch {
382+
case err != nil:
382383
return err
384+
case len(rawArr) != 1:
385+
return fmt.Errorf("protocol violation; expected 1 array, got %d", len(rawArr))
383386
}
384387

385388
privileges := make([]Privilege, len(rawArr[0]))

box/session.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ type Session struct {
1212
conn tarantool.Doer // Connection interface for interacting with Tarantool.
1313
}
1414

15-
// NewSession creates a new Session instance, taking a Tarantool connection as an argument.
16-
func NewSession(conn tarantool.Doer) *Session {
15+
// newSession creates a new Session instance, taking a Tarantool connection as an argument.
16+
func newSession(conn tarantool.Doer) *Session {
1717
return &Session{conn: conn} // Pass the connection to the Session structure.
1818
}
1919

2020
// Session method returns a new Session object associated with the Box instance.
2121
func (b *Box) Session() *Session {
22-
return NewSession(b.conn)
22+
return newSession(b.conn)
2323
}
2424

2525
// SessionSuRequest struct wraps a Tarantool call request specifically for session switching.
@@ -48,17 +48,18 @@ func NewSessionSuRequest(username string, execute ...any) (SessionSuRequest, err
4848
}
4949

5050
// Su method is used to switch the session to the specified username.
51-
// It sends the request to Tarantool and returns a future response or an error.
52-
func (s *Session) Su(ctx context.Context, username string,
53-
execute ...any) (*tarantool.Future, error) {
51+
// It sends the request to Tarantool and returns an error.
52+
func (s *Session) Su(ctx context.Context, username string) error {
5453
// Create a request and send it to Tarantool.
55-
req, err := NewSessionSuRequest(username, execute...)
54+
req, err := NewSessionSuRequest(username)
5655
if err != nil {
57-
return nil, err // Return any errors encountered while creating the request.
56+
return err // Return any errors encountered while creating the request.
5857
}
5958

6059
req.Context(ctx) // Attach the context to the request for cancellation and timeout.
6160

6261
// Execute the request and return the future response, or an error.
63-
return s.conn.Do(req), nil
62+
fut := s.conn.Do(req)
63+
_, err = fut.GetResponse()
64+
return err
6465
}

box/session_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
package box
22

33
import (
4+
th "github.com/tarantool/go-tarantool/v2/test_helpers"
45
"testing"
56

67
"github.com/stretchr/testify/require"
78
)
89

910
func TestBox_Session(t *testing.T) {
10-
b := New(nil)
11+
b := New(th.Ptr(th.NewMockDoer(t)))
1112
require.NotNil(t, b.Session())
1213
}
1314

1415
func TestNewSession(t *testing.T) {
1516
require.NotPanics(t, func() {
16-
NewSession(nil)
17+
newSession(nil)
1718
})
1819
}
1920

box/tarantool_test.go

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -478,11 +478,9 @@ func TestBox_Sugar_Schema_UserGrant_WithSu(t *testing.T) {
478478
startPrivilages, err := b.Schema().User().Info(ctx, username)
479479
require.NoError(t, err)
480480

481-
future, err := b.Session().Su(ctx, "admin")
481+
err = b.Session().Su(ctx, "admin")
482482
require.NoError(t, err)
483483

484-
_, err = future.Get()
485-
486484
require.NoError(t, err, "default user in super group")
487485

488486
newPrivilege := box.Privilege{
@@ -565,11 +563,9 @@ func TestSchemaUser_Revoke_WithSu(t *testing.T) {
565563
startPrivileges, err := b.Schema().User().Info(ctx, username)
566564
require.NoError(t, err)
567565

568-
future, err := b.Session().Su(ctx, "admin")
566+
err = b.Session().Su(ctx, "admin")
569567
require.NoError(t, err)
570568

571-
_, err = future.Get()
572-
573569
require.NoError(t, err, "dialer user in super group")
574570

575571
require.NotEmpty(t, startPrivileges)
@@ -614,9 +610,8 @@ func TestSchemaUser_Revoke_NonExistsPermission(t *testing.T) {
614610
startPrivileges, err := b.Schema().User().Info(ctx, username)
615611
require.NoError(t, err)
616612

617-
future, err := b.Session().Su(ctx, "admin")
613+
err = b.Session().Su(ctx, "admin")
618614
require.NoError(t, err)
619-
_, err = future.Get()
620615

621616
require.NoError(t, err, "dialer user in super group")
622617

@@ -637,18 +632,6 @@ func TestSchemaUser_Revoke_NonExistsPermission(t *testing.T) {
637632
require.Error(t, err)
638633
}
639634

640-
func TestSession_Su_WithCall(t *testing.T) {
641-
ctx := context.TODO()
642-
643-
conn, err := tarantool.Connect(ctx, dialer, tarantool.Opts{})
644-
require.NoError(t, err)
645-
646-
b := box.New(conn)
647-
648-
_, err = b.Session().Su(ctx, "admin", "echo", 1, 2)
649-
require.Error(t, err, "unsupported now")
650-
}
651-
652635
func TestSession_Su_AdminPermissions(t *testing.T) {
653636
ctx := context.TODO()
654637

@@ -657,7 +640,7 @@ func TestSession_Su_AdminPermissions(t *testing.T) {
657640

658641
b := box.New(conn)
659642

660-
_, err = b.Session().Su(ctx, "admin")
643+
err = b.Session().Su(ctx, "admin")
661644
require.NoError(t, err)
662645
}
663646

test_helpers/doer.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,7 @@ func (doer *MockDoer) Do(req tarantool.Request) *tarantool.Future {
6767

6868
return fut
6969
}
70+
71+
func Ptr[T any](val T) *T {
72+
return &val
73+
}

0 commit comments

Comments
 (0)