Skip to content

Commit 609ddf6

Browse files
committed
test(systemtests): add gRPC systemtest for node Status endpoint
1 parent 0df5ce9 commit 609ddf6

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//go:build system_test
2+
3+
package systemtests
4+
5+
import (
6+
"context"
7+
"fmt"
8+
"path/filepath"
9+
"strconv"
10+
"testing"
11+
12+
"github.com/creachadair/tomledit"
13+
"github.com/creachadair/tomledit/parser"
14+
"github.com/stretchr/testify/assert"
15+
"github.com/stretchr/testify/require"
16+
"google.golang.org/grpc"
17+
"google.golang.org/grpc/credentials/insecure"
18+
19+
"cosmossdk.io/systemtests"
20+
21+
"github.com/cosmos/cosmos-sdk/client/grpc/node"
22+
)
23+
24+
// TestNodeStatusGRPC tests the Status gRPC endpoint to verify earliest_store_height.
25+
func TestNodeStatusGRPC(t *testing.T) {
26+
sut := systemtests.Sut
27+
sut.ResetChain(t)
28+
sut.StartChain(t)
29+
sut.AwaitNBlocks(t, 3)
30+
31+
grpcAddr := fmt.Sprintf("localhost:%d", 9090)
32+
conn, err := grpc.NewClient(grpcAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
33+
require.NoError(t, err)
34+
defer conn.Close()
35+
36+
queryClient := node.NewServiceClient(conn)
37+
38+
t.Run("returns valid store heights", func(t *testing.T) {
39+
resp, err := queryClient.Status(context.Background(), &node.StatusRequest{})
40+
require.NoError(t, err)
41+
t.Logf("Status response: earliest_store_height=%d, height=%d", resp.EarliestStoreHeight, resp.Height)
42+
43+
assert.GreaterOrEqual(t, resp.EarliestStoreHeight, uint64(1))
44+
assert.GreaterOrEqual(t, resp.Height, uint64(1))
45+
assert.GreaterOrEqual(t, resp.Height, resp.EarliestStoreHeight)
46+
})
47+
48+
t.Run("earliest stable on unpruned chain", func(t *testing.T) {
49+
resp1, err := queryClient.Status(context.Background(), &node.StatusRequest{})
50+
require.NoError(t, err)
51+
initial := resp1.EarliestStoreHeight
52+
53+
sut.AwaitNBlocks(t, 2)
54+
55+
resp2, err := queryClient.Status(context.Background(), &node.StatusRequest{})
56+
require.NoError(t, err)
57+
assert.Equal(t, initial, resp2.EarliestStoreHeight)
58+
})
59+
}
60+
61+
// TestNodeStatusWithStatePruning tests earliest_store_height increases with state pruning.
62+
func TestNodeStatusWithStatePruning(t *testing.T) {
63+
const pruningKeepRecent = 5
64+
const pruningInterval = 10
65+
66+
sut := systemtests.Sut
67+
sut.ResetChain(t)
68+
69+
// Configure state pruning
70+
for i := 0; i < sut.NodesCount(); i++ {
71+
appTomlPath := filepath.Join(sut.NodeDir(i), "config", "app.toml")
72+
systemtests.EditToml(appTomlPath, func(doc *tomledit.Document) {
73+
setNodeString(doc, "custom", "pruning")
74+
setNodeString(doc, strconv.Itoa(pruningKeepRecent), "pruning-keep-recent")
75+
setNodeString(doc, strconv.Itoa(pruningInterval), "pruning-interval")
76+
})
77+
}
78+
79+
sut.StartChain(t)
80+
81+
grpcAddr := fmt.Sprintf("localhost:%d", 9090)
82+
conn, err := grpc.NewClient(grpcAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
83+
require.NoError(t, err)
84+
defer conn.Close()
85+
86+
queryClient := node.NewServiceClient(conn)
87+
88+
resp, err := queryClient.Status(context.Background(), &node.StatusRequest{})
89+
require.NoError(t, err)
90+
initialEarliest := resp.EarliestStoreHeight
91+
t.Logf("Initial: earliest_store_height=%d, height=%d", initialEarliest, resp.Height)
92+
93+
// Wait for pruning to occur
94+
blocksToWait := pruningInterval + pruningKeepRecent + 5
95+
t.Logf("Waiting %d blocks for state pruning...", blocksToWait)
96+
sut.AwaitNBlocks(t, int64(blocksToWait))
97+
98+
resp, err = queryClient.Status(context.Background(), &node.StatusRequest{})
99+
require.NoError(t, err)
100+
t.Logf("After %d blocks: earliest_store_height=%d, height=%d", blocksToWait, resp.EarliestStoreHeight, resp.Height)
101+
102+
assert.Greater(t, resp.EarliestStoreHeight, initialEarliest,
103+
"earliest_store_height should increase after pruning")
104+
assert.GreaterOrEqual(t, resp.Height, resp.EarliestStoreHeight)
105+
}
106+
107+
func setNodeString(doc *tomledit.Document, val string, xpath ...string) {
108+
e := doc.First(xpath...)
109+
if e == nil {
110+
panic(fmt.Sprintf("not found: %v", xpath))
111+
}
112+
e.Value = parser.MustValue(fmt.Sprintf("%q", val))
113+
}

0 commit comments

Comments
 (0)