Skip to content

Commit ea922af

Browse files
committed
tests(self-healing): stabilize role selection with canonical hash flow
1 parent 1f08128 commit ea922af

2 files changed

Lines changed: 9 additions & 56 deletions

File tree

supernode/transport/grpc/self_healing/handler_e2e_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ func TestSelfHealingE2E_RequestThenVerify(t *testing.T) {
238238

239239
recConn, recCleanup := startSelfHealingTestServer(t, "recipient-1", recipientP2P, lumeraClient, factory)
240240
defer recCleanup()
241-
obsConn, obsCleanup := startSelfHealingTestServer(t, "observer-1", observerP2P, nil, nil)
241+
obsConn, obsCleanup := startSelfHealingTestServer(t, "observer-1", observerP2P, lumeraClient, nil)
242242
defer obsCleanup()
243243

244244
recClient := supernode.NewSelfHealingServiceClient(recConn)

tests/system/e2e_self_healing_test.go

Lines changed: 8 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,8 @@ const (
4545
)
4646

4747
type selfHealingNode struct {
48-
KeyName string
4948
Identity string
5049
GRPCAddr string
51-
HasLocal bool
5250
}
5351

5452
type selfHealingRPCClient struct {
@@ -186,36 +184,18 @@ func TestSelfHealingE2EHappyPath(t *testing.T) {
186184
require.NoError(t, err)
187185

188186
nodes := []selfHealingNode{
189-
{KeyName: shNode0KeyName, Identity: shNode0Identity},
190-
{KeyName: shNode1KeyName, Identity: shNode1Identity},
191-
{KeyName: shNode2KeyName, Identity: shNode2Identity},
187+
{Identity: shNode0Identity},
188+
{Identity: shNode1Identity},
189+
{Identity: shNode2Identity},
192190
}
193191
for i := range nodes {
194192
nodes[i].GRPCAddr = mustGetSupernodeLatestAddr(t, userLumera, nodes[i].Identity)
195-
nodes[i].HasLocal = nodeHasLocalCopy(t, shClient, nodes[i], fileKey)
196193
}
197194

198-
var recipient selfHealingNode
199-
recipientForcedReconstruct := false
200-
for _, n := range nodes {
201-
if !n.HasLocal {
202-
recipient = n
203-
recipientForcedReconstruct = true
204-
break
205-
}
206-
}
207-
if recipient.Identity == "" {
208-
recipient = nodes[1]
209-
}
210-
211-
observer := recipient
212-
for _, n := range nodes {
213-
if n.Identity != recipient.Identity && n.HasLocal {
214-
observer = n
215-
break
216-
}
217-
}
218-
t.Logf("self-healing role selection recipient=%s recipient_has_local=%t observer=%s observer_has_local=%t", recipient.Identity, recipient.HasLocal, observer.Identity, observer.HasLocal)
195+
// Keep roles deterministic and distinct in system tests.
196+
recipient := nodes[1]
197+
observer := nodes[2]
198+
t.Logf("self-healing role selection recipient=%s observer=%s", recipient.Identity, observer.Identity)
219199

220200
challengeID := fmt.Sprintf("sh-e2e-happy-%d", time.Now().UnixNano())
221201
req := &pb.RequestSelfHealingRequest{
@@ -237,9 +217,7 @@ func TestSelfHealingE2EHappyPath(t *testing.T) {
237217
t.Logf("self-healing request response accepted=%t reconstruction_required=%t reconstructed_hash=%s", reqRespSH.Accepted, reqRespSH.ReconstructionRequired, reqRespSH.ReconstructedHashHex)
238218
require.True(t, strings.EqualFold(reqRespSH.ReconstructedHashHex, registeredHashHex), "recipient reconstructed hash mismatch: got=%s want=%s", reqRespSH.ReconstructedHashHex, registeredHashHex)
239219
t.Logf("self-healing hash assertion passed reconstructed_hash=%s registered_action_hash=%s", reqRespSH.ReconstructedHashHex, registeredHashHex)
240-
if recipientForcedReconstruct {
241-
require.True(t, reqRespSH.ReconstructionRequired, "expected reconstruction_required=true when recipient initially lacked local key")
242-
}
220+
require.True(t, reqRespSH.ReconstructionRequired, "expected reconstruction_required=true for RQ artifact key healing")
243221

244222
verifyReq := &pb.VerifySelfHealingRequest{
245223
ChallengeId: challengeID,
@@ -345,31 +323,6 @@ func mustGetSupernodeLatestAddr(t *testing.T, client lumera.Client, identity str
345323
return addr
346324
}
347325

348-
func nodeHasLocalCopy(t *testing.T, shClient *selfHealingRPCClient, node selfHealingNode, fileKey string) bool {
349-
t.Helper()
350-
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
351-
defer cancel()
352-
probeReq := &pb.VerifySelfHealingRequest{
353-
ChallengeId: fmt.Sprintf("sh-probe-%s-%d", node.KeyName, time.Now().UnixNano()),
354-
EpochId: 0,
355-
FileKey: fileKey,
356-
RecipientId: "",
357-
ReconstructedHashHex: strings.Repeat("0", 64),
358-
ObserverId: node.Identity,
359-
ActionId: "probe-local-only-invalid-action",
360-
}
361-
resp, err := shClient.Verify(ctx, node.Identity, node.GRPCAddr, probeReq)
362-
require.NoError(t, err)
363-
if resp == nil {
364-
return false
365-
}
366-
errLower := strings.ToLower(strings.TrimSpace(resp.Error))
367-
if strings.Contains(errLower, "observer reconstruction failed") || strings.Contains(errLower, "action resolution failed") {
368-
return false
369-
}
370-
return true
371-
}
372-
373326
func pickAnchorKey(keys []string) string {
374327
anchor := ""
375328
for _, raw := range keys {

0 commit comments

Comments
 (0)