Skip to content

Commit 817bc76

Browse files
committed
go/oasis-test-runner/e2e: Add create import checkpoint test
The test should be ideally hardened by also making sure the target node also syncs up to the tip of the runtime chain and not just consensus. Furthermore, given that e2e tests are expensive and meant to test complex scenarios, my suggestions would be to also run prune, compact, and inspect command on the source node prior to creating a checkpoint. This way we would "smoke test" remaining storage commands, and the scenario could be called storaged_cmds instead.
1 parent aeb752b commit 817bc76

2 files changed

Lines changed: 151 additions & 0 deletions

File tree

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
package runtime
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"path/filepath"
7+
8+
consensus "github.com/oasisprotocol/oasis-core/go/consensus/api"
9+
"github.com/oasisprotocol/oasis-core/go/oasis-test-runner/env"
10+
"github.com/oasisprotocol/oasis-core/go/oasis-test-runner/oasis"
11+
"github.com/oasisprotocol/oasis-core/go/oasis-test-runner/oasis/cli"
12+
"github.com/oasisprotocol/oasis-core/go/oasis-test-runner/scenario"
13+
roothash "github.com/oasisprotocol/oasis-core/go/roothash/api"
14+
)
15+
16+
// CheckpointCreateImport is the checkpoint create/import e2e scenario.
17+
var CheckpointCreateImport scenario.Scenario = newCheckpointCreateImportImpl()
18+
19+
type checkpointCreateImportImpl struct {
20+
Scenario
21+
}
22+
23+
func newCheckpointCreateImportImpl() scenario.Scenario {
24+
return &checkpointCreateImportImpl{
25+
Scenario: *NewScenario(
26+
"checkpoint-create-import",
27+
NewTestClient().WithScenario(SimpleScenario),
28+
),
29+
}
30+
}
31+
32+
func (sc *checkpointCreateImportImpl) Clone() scenario.Scenario {
33+
return &checkpointCreateImportImpl{
34+
Scenario: *sc.Scenario.Clone().(*Scenario),
35+
}
36+
}
37+
38+
func (sc *checkpointCreateImportImpl) Fixture() (*oasis.NetworkFixture, error) {
39+
return sc.Scenario.Fixture()
40+
}
41+
42+
func (sc *checkpointCreateImportImpl) Run(ctx context.Context, childEnv *env.Env) error {
43+
// Start the network and run the test client to populate state.
44+
if err := sc.StartNetworkAndTestClient(ctx, childEnv); err != nil {
45+
return err
46+
}
47+
if err := sc.WaitTestClient(); err != nil {
48+
return err
49+
}
50+
51+
// Use height - 3 so that blocks at h, h+1, h+2 all exist in the block store.
52+
blk, err := sc.Net.Controller().Consensus.GetBlock(ctx, consensus.HeightLatest)
53+
if err != nil {
54+
return fmt.Errorf("failed to get latest consensus block: %w", err)
55+
}
56+
height := blk.Height - 3
57+
58+
rtBlk, err := sc.Net.ClientController().Roothash.GetLatestBlock(ctx, &roothash.RuntimeRequest{
59+
RuntimeID: KeyValueRuntimeID,
60+
Height: consensus.HeightLatest,
61+
})
62+
if err != nil {
63+
return fmt.Errorf("failed to get latest runtime block: %w", err)
64+
}
65+
round := rtBlk.Header.Round
66+
67+
sc.Logger.Info("creating checkpoints",
68+
"height", height,
69+
"round", round,
70+
"runtime_id", KeyValueRuntimeID,
71+
)
72+
73+
cpDir := filepath.Join(childEnv.Dir(), "checkpoint")
74+
75+
// Stop compute worker 0 (source node).
76+
source := sc.Net.ComputeWorkers()[0]
77+
if err := source.StopGracefully(); err != nil {
78+
return fmt.Errorf("failed to stop source compute worker: %w", err)
79+
}
80+
81+
// Create checkpoints from the source node's data.
82+
args := []string{
83+
"storage", "checkpoint", "create",
84+
"--config", source.ConfigFile(),
85+
"--height", fmt.Sprintf("%d", height),
86+
"--runtime", KeyValueRuntimeID.Hex(),
87+
"--round", fmt.Sprintf("%d", round),
88+
"--output-dir", cpDir,
89+
"--debug.dont_blame_oasis",
90+
"--debug.allow_test_keys",
91+
}
92+
if err := cli.RunSubCommand(childEnv, sc.Logger, "checkpoint-create", sc.Net.Config().NodeBinary, args); err != nil {
93+
return fmt.Errorf("failed to create checkpoints: %w", err)
94+
}
95+
96+
sc.Logger.Info("checkpoints created successfully")
97+
98+
// Start the source compute worker again.
99+
if err := source.Start(); err != nil {
100+
return fmt.Errorf("failed to restart source compute worker: %w", err)
101+
}
102+
103+
// Stop compute worker 2 (target node).
104+
target := sc.Net.ComputeWorkers()[2]
105+
if err := target.StopGracefully(); err != nil {
106+
return fmt.Errorf("failed to stop target compute worker: %w", err)
107+
}
108+
109+
// Reset the target node's state completely. Ideally we would use NoAutoStart,
110+
// however if we do so no config is created until the node is started and import
111+
// command therefore fails.
112+
sc.Logger.Info("resetting target node state")
113+
cliHelpers := cli.New(childEnv, sc.Net, sc.Logger)
114+
if err := cliHelpers.UnsafeReset(target.DataDir(), false, false, true); err != nil {
115+
return fmt.Errorf("failed to reset target node state: %w", err)
116+
}
117+
118+
// Import checkpoints into the target node.
119+
sc.Logger.Info("importing checkpoints into target node")
120+
args = []string{
121+
"storage", "checkpoint", "import",
122+
"--config", target.ConfigFile(),
123+
"--input-dir", cpDir,
124+
"--debug.dont_blame_oasis",
125+
"--debug.allow_test_keys",
126+
}
127+
if err := cli.RunSubCommand(childEnv, sc.Logger, "checkpoint-import", sc.Net.Config().NodeBinary, args); err != nil {
128+
return fmt.Errorf("failed to import checkpoints: %w", err)
129+
}
130+
131+
sc.Logger.Info("checkpoints imported, starting target node")
132+
133+
// Start the target node.
134+
if err := target.Start(); err != nil {
135+
return fmt.Errorf("failed to start target node: %w", err)
136+
}
137+
138+
// Wait for the target node to sync.
139+
sc.Logger.Info("waiting for target node to sync")
140+
ctrl, err := oasis.NewController(target.SocketPath())
141+
if err != nil {
142+
return fmt.Errorf("failed to create controller for target node: %w", err)
143+
}
144+
if err := ctrl.WaitReady(ctx); err != nil {
145+
return fmt.Errorf("target node failed to sync: %w", err)
146+
}
147+
148+
return nil
149+
}

go/oasis-test-runner/scenario/e2e/runtime/scenario.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,8 @@ func RegisterScenarios() error {
347347
StorageSyncFromRegistered,
348348
StorageSyncInconsistent,
349349
StorageEarlyStateSync,
350+
// Checkpoint create/import test.
351+
CheckpointCreateImport,
350352
// Sentry test.
351353
Sentry,
352354
// Keymanager tests.

0 commit comments

Comments
 (0)