Skip to content

Commit f93c9a6

Browse files
author
Maksim Konovalov
committed
feature/box: first box and box.info implementation
I implemented the box interface for tarantool with a small number of fields, which in the future can be supplemented
1 parent 8cf8673 commit f93c9a6

File tree

4 files changed

+164
-0
lines changed

4 files changed

+164
-0
lines changed

box/box.go

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package box
2+
3+
import (
4+
"github.com/tarantool/go-tarantool/v2"
5+
)
6+
7+
// Box defines an interface for interacting with a Tarantool instance.
8+
// It includes the Info method, which retrieves instance information.
9+
type Box interface {
10+
Info() (Info, error) // Retrieves detailed information about the Tarantool instance.
11+
}
12+
13+
// box is a concrete implementation of the Box interface.
14+
// It holds a connection to the Tarantool instance via the Doer interface.
15+
type box struct {
16+
conn tarantool.Doer // Connection interface for interacting with Tarantool.
17+
}
18+
19+
// By returns a new instance of the box structure, which implements the Box interface.
20+
func By(conn tarantool.Doer) Box {
21+
return &box{
22+
conn: conn, // Assigns the provided Tarantool connection.
23+
}
24+
}

box/box_test.go

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package box_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
"github.com/tarantool/go-tarantool/v2/box"
8+
)
9+
10+
func TestBy(t *testing.T) {
11+
// We expect a panic because we are passing a nil connection (nil Doer) to the By function.
12+
// The library does not control this zone, and the nil connection would cause a runtime error
13+
// when we attempt to call methods (like Info) on it. This test ensures that such an invalid state
14+
// is correctly handled by causing a panic, as it's outside of the library's responsibility.
15+
require.Panics(t, func() {
16+
// Create a box instance with a nil connection. This should lead to a panic later.
17+
b := box.By(nil)
18+
19+
// Ensure the box instance is not nil (which it shouldn't be), but this is not meaningful
20+
// since we will panic when we call the Info method with the nil connection.
21+
require.NotNil(t, b)
22+
23+
// Calling Info on a box with a nil connection will result in a panic, since the underlying
24+
// connection (Doer) cannot perform the requested action (it's nil).
25+
_, _ = b.Info()
26+
})
27+
}

box/info.go

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package box
2+
3+
import "github.com/tarantool/go-tarantool/v2"
4+
5+
// ClusterInfo represents information about the cluster.
6+
// It contains the unique identifier (UUID) of the cluster.
7+
type ClusterInfo struct {
8+
UUID string `msgpack:"uuid"`
9+
}
10+
11+
// Info represents detailed information about the Tarantool instance.
12+
// It includes version, node ID, read-only status, process ID, cluster information, and more.
13+
type Info struct {
14+
Version string `msgpack:"version"` // The version of the Tarantool instance.
15+
ID *int `msgpack:"id"` // The node ID (nullable).
16+
RO bool `msgpack:"ro"` // Read-only status of the instance.
17+
UUID string `msgpack:"uuid"` // Unique identifier of the instance.
18+
PID int `msgpack:"pid"` // Process ID of the instance.
19+
Status string `msgpack:"status"` // Current status of the instance (e.g., running, unconfigured).
20+
Lsn uint64 `msgpack:"lsn"` // Log sequence number of the instance.
21+
Cluster ClusterInfo `msgpack:"cluster"` // Cluster information, including cluster UUID.
22+
}
23+
24+
// Info retrieves the current information of the Tarantool instance.
25+
// It calls the "box.info" function and parses the result into the Info structure.
26+
func (b *box) Info() (Info, error) {
27+
var info Info
28+
29+
// Call "box.info" to get instance information from Tarantool.
30+
fut := b.conn.Do(tarantool.NewCallRequest("box.info"))
31+
32+
// Parse the result into the Info structure.
33+
err := fut.GetTyped(&[]interface{}{&info})
34+
if err != nil {
35+
return Info{}, err
36+
}
37+
38+
// Return the parsed info and any potential error.
39+
return info, err
40+
}

box/tarantool_test.go

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package box_test
2+
3+
import (
4+
"context"
5+
"log"
6+
"os"
7+
"testing"
8+
"time"
9+
10+
"github.com/google/uuid"
11+
"github.com/stretchr/testify/require"
12+
"github.com/tarantool/go-tarantool/v2"
13+
"github.com/tarantool/go-tarantool/v2/box"
14+
"github.com/tarantool/go-tarantool/v2/test_helpers"
15+
)
16+
17+
var server = "127.0.0.1:3013"
18+
var dialer = tarantool.NetDialer{
19+
Address: server,
20+
User: "test",
21+
Password: "test",
22+
}
23+
24+
func validateUUID(t *testing.T, u string) {
25+
var err error
26+
27+
_, err = uuid.Parse(u)
28+
29+
require.NoError(t, err)
30+
}
31+
32+
func TestBox_Info(t *testing.T) {
33+
ctx := context.TODO()
34+
35+
conn, err := tarantool.Connect(ctx, dialer, tarantool.Opts{})
36+
require.NoError(t, err)
37+
38+
info, err := box.By(conn).Info()
39+
require.NoError(t, err)
40+
41+
// check all fields run correctly
42+
validateUUID(t, info.UUID)
43+
validateUUID(t, info.Cluster.UUID)
44+
45+
require.NotEmpty(t, info.Version)
46+
// check that pid parsed correctly
47+
require.NotEqual(t, info.PID, 0)
48+
49+
}
50+
51+
func runTestMain(m *testing.M) int {
52+
instance, err := test_helpers.StartTarantool(test_helpers.StartOpts{
53+
Dialer: dialer,
54+
InitScript: "testdata/config-memtx.lua",
55+
Listen: server,
56+
WaitStart: 100 * time.Millisecond,
57+
ConnectRetry: 10,
58+
RetryTimeout: 500 * time.Millisecond,
59+
})
60+
defer test_helpers.StopTarantoolWithCleanup(instance)
61+
62+
if err != nil {
63+
log.Printf("Failed to prepare test Tarantool: %s", err)
64+
return 1
65+
}
66+
67+
return m.Run()
68+
}
69+
70+
func TestMain(m *testing.M) {
71+
code := runTestMain(m)
72+
os.Exit(code)
73+
}

0 commit comments

Comments
 (0)