Skip to content

Commit a63a830

Browse files
kishanpsSRAVANI KANASANI
authored andcommitted
Wait for gNOI server to be down after reboot request.
1 parent 226fcd8 commit a63a830

File tree

7 files changed

+323
-78
lines changed

7 files changed

+323
-78
lines changed

sdn_tests/pins_ondatra/infrastructure/testhelper/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ go_library(
2626
"platform_info.go",
2727
"port_management.go",
2828
"results.go",
29+
"utils.go",
2930
"ssh.go",
3031
"//infrastructure/testhelper/platform_info:platform_info",
3132
],

sdn_tests/pins_ondatra/infrastructure/testhelper/config_convergence.go

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -174,26 +174,6 @@ func CompareConfigAndStateValues(ctx context.Context, t *testing.T, dut *ondatra
174174
return r.String(), nil
175175
}
176176

177-
// pollFunc returns true if the condition is met.
178-
type pollFunc func() bool
179-
180-
// poll polls the condition until it is met or the context is done.
181-
func poll(ctx context.Context, t *testing.T, interval time.Duration, pf pollFunc) error {
182-
ticker := time.NewTicker(interval)
183-
defer ticker.Stop()
184-
for {
185-
select {
186-
case <-ctx.Done():
187-
return fmt.Errorf("polling for condition failed, err: %v", ctx.Err())
188-
case <-ticker.C:
189-
if pf() {
190-
log.InfoContextf(ctx, "polling done")
191-
return nil
192-
}
193-
}
194-
}
195-
}
196-
197177
// WaitForConfigConvergence checks for differences between config and state.
198178
// Polls till configConvergenceTimeout,
199179
// returns error if the difference still exists.
@@ -208,18 +188,18 @@ func WaitForConfigConvergence(ctx context.Context, t *testing.T, dut *ondatra.DU
208188
defer cancel()
209189
dutName := dut.Name()
210190
// Poll until the config and state are similar.
211-
return poll(ctx, t, configConvergencePollInterval, func() bool {
191+
return poll(ctx, configConvergencePollInterval, func() pollStatus {
212192
diff, err := CompareConfigAndStateValues(ctx, t, dut, config)
213193
if err != nil {
214194
log.InfoContextf(ctx, "Comparing config and state failed for dut: %v, err: %v", dutName, err)
215-
return false
195+
return continuePoll
216196
}
217197
if diff == "" {
218198
log.InfoContextf(ctx, "Config and state converged for dut: %v", dutName)
219-
return true
199+
return exitPoll
220200
}
221201
log.InfoContextf(ctx, "diff in config and state found for dut: %v\ndiff_begin:\n%v\ndiff_end\n", dutName, diff)
222-
return false
202+
return continuePoll
223203
})
224204
}
225205

@@ -369,30 +349,30 @@ func WaitForSwitchState(ctx context.Context, t *testing.T, dut *ondatra.DUTDevic
369349
defer cancel()
370350

371351
// Poll until the switch is ready or the context is done.
372-
err := poll(ctx, t, switchStatePollInterval, func() bool {
352+
err := poll(ctx, switchStatePollInterval, func() pollStatus {
373353
switch s := switchState; s {
374354
case down:
375355
if err := GNOIAble(t, dut); err != nil {
376356
log.InfoContextf(ctx, "GNOIAble(dut=%v) failed, err: %v", dutName, err)
377-
return false
357+
return continuePoll
378358
}
379359
switchState++
380360
case gnoiAble:
381361
if err := GNMIAble(t, dut); err != nil {
382362
log.InfoContextf(ctx, "GNMIAble(dut=%v) failed, err: %v", dutName, err)
383-
return false
363+
return continuePoll
384364
}
385365
switchState++
386366
case gnmiAble:
387367
if err := WaitForAllPortsUp(ctx, t, dut); err != nil {
388368
log.InfoContextf(ctx, "WaitForAllPortsUp(dut=%v) failed, err: %v", dutName, err)
389-
return false
369+
return continuePoll
390370
}
391371
switchState++
392372
case portsUp:
393-
return true
373+
return exitPoll
394374
}
395-
return false
375+
return continuePoll
396376
})
397377

398378
if err == nil {

sdn_tests/pins_ondatra/infrastructure/testhelper/gnoi.go

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,20 @@ var (
4444

4545
// RebootParams specify the reboot parameters used by the Reboot API.
4646
type RebootParams struct {
47-
request any
48-
waitTime time.Duration
49-
checkInterval time.Duration
50-
lmTTkrID string // latency measurement testtracker UUID
51-
lmTitle string // latency measurement title
47+
request any
48+
waitTime time.Duration
49+
checkInterval time.Duration
50+
requestTimeout time.Duration
51+
lmTTkrID string // latency measurement testtracker UUID
52+
lmTitle string // latency measurement title
5253
}
5354

5455
// NewRebootParams returns RebootParams structure with default values.
5556
func NewRebootParams() *RebootParams {
5657
return &RebootParams{
57-
waitTime: 4 * time.Minute,
58-
checkInterval: 20 * time.Second,
58+
waitTime: 4 * time.Minute,
59+
checkInterval: 20 * time.Second,
60+
requestTimeout: 2 * time.Minute,
5961
}
6062
}
6163

@@ -82,6 +84,14 @@ func (p *RebootParams) WithRequest(r any) *RebootParams {
8284
return p
8385
}
8486

87+
// WithRequestTimeout adds the timeout for the reboot request.
88+
// The function will wait for the gNOI server to be down within this duration.
89+
// Default value is 2 minutes.
90+
func (p *RebootParams) WithRequestTimeout(timeout time.Duration) *RebootParams {
91+
p.requestTimeout = timeout
92+
return p
93+
}
94+
8595
// WithLatencyMeasurement adds testtracker uuid and title for latency measurement.
8696
func (p *RebootParams) WithLatencyMeasurement(testTrackerID, title string) *RebootParams {
8797
p.lmTTkrID = testTrackerID
@@ -132,28 +142,47 @@ func Reboot(t *testing.T, d *ondatra.DUTDevice, params *RebootParams) error {
132142
return nil
133143
}
134144

135-
log.Infof("Polling gNOI server reachability in %v intervals for max duration of %v", params.checkInterval, params.waitTime)
145+
rebootRequestTimeout := params.requestTimeout
146+
ctx, cancel := context.WithTimeout(context.Background(), rebootRequestTimeout)
147+
defer cancel()
148+
149+
// The switch backend might not have processed the request or might take
150+
// sometime to execute the request. So poll for the gNOI server to be down,
151+
// or context to expire.
152+
pollErr := poll(ctx, 10*time.Second /*(pollInterval)*/, func() pollStatus {
153+
err := GNOIAble(t, d)
154+
timeElapsed := (time.Now().UnixNano() - timeBeforeReboot) / int64(time.Second)
155+
if err == nil {
156+
log.Infof("gNOI server is still up after %v seconds", timeElapsed)
157+
return continuePoll
158+
}
159+
log.Infof("gNOI server is down after %v seconds, got error while checking gNOI server reachability: %v as expected", timeElapsed, err)
160+
return exitPoll
161+
})
162+
if pollErr != nil {
163+
log.WarningContextf(ctx, "Polling gNOI server to be down within time: %v failed: %v", rebootRequestTimeout, pollErr)
164+
log.InfoContextf(ctx, "Continue to check if the switch has rebooted")
165+
}
166+
167+
log.InfoContextf(ctx, "Polling gNOI server reachability in %v intervals for max duration of %v", params.checkInterval, params.waitTime)
136168
for timeout := time.Now().Add(params.waitTime); time.Now().Before(timeout); {
137-
// The switch backend might not have processed the request or might take
138-
// sometime to execute the request. So wait for check interval time and
139-
// later verify that the switch rebooted within the specified wait time.
140169
time.Sleep(params.checkInterval)
141170
doneTime := time.Now()
142171
timeElapsed := (doneTime.UnixNano() - timeBeforeReboot) / int64(time.Second)
143172

144173
if err := GNOIAble(t, d); err != nil {
145-
log.Infof("gNOI server not up after %v seconds", timeElapsed)
174+
log.InfoContextf(ctx, "gNOI server not up after %v seconds", timeElapsed)
146175
continue
147176
}
148-
log.Infof("gNOI server up after %v seconds", timeElapsed)
177+
log.InfoContextf(ctx, "gNOI server up after %v seconds", timeElapsed)
149178

150179
// An extra check to ensure that the system has rebooted.
151180
if bootTime := gnmiSystemBootTimeGet(t, d); bootTime < uint64(timeBeforeReboot) {
152-
log.Infof("Switch has not rebooted after %v seconds", timeElapsed)
181+
log.InfoContextf(ctx, "Switch has not rebooted after %v seconds", timeElapsed)
153182
continue
154183
}
155184

156-
log.Infof("Switch rebooted after %v seconds", timeElapsed)
185+
log.InfoContextf(ctx, "Switch rebooted after %v seconds", timeElapsed)
157186
return nil
158187
}
159188

sdn_tests/pins_ondatra/infrastructure/testhelper/p4rt.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515

1616
"github.com/openconfig/ondatra"
1717
"github.com/openconfig/ondatra/gnmi"
18+
"github.com/openconfig/ygnmi/ygnmi"
1819
"github.com/pkg/errors"
1920
"google.golang.org/grpc/codes"
2021
"google.golang.org/protobuf/encoding/prototext"
@@ -35,15 +36,29 @@ var (
3536
return 0, errors.Errorf("failed to get port ID for port %v from switch", port)
3637
}
3738
testhelperDeviceIDGet = func(t *testing.T, d *ondatra.DUTDevice) (uint64, error) {
38-
deviceInfo, present := gnmi.Lookup(t, d, gnmi.OC().Component(icName).IntegratedCircuit().State()).Val()
39+
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
40+
defer cancel()
41+
yc, err := ygnmiClient(ctx, d)
42+
if err != nil {
43+
return 0, fmt.Errorf("failed to create ygnmi client, err: %v", err)
44+
}
45+
v, err := ygnmi.Lookup(ctx, yc, gnmi.OC().Component(icName).IntegratedCircuit().State())
46+
if err != nil {
47+
return 0, fmt.Errorf("failed to lookup device ID, err: %v", err)
48+
}
49+
deviceInfo, present := v.Val()
3950
if present && deviceInfo.NodeId != nil {
4051
return *deviceInfo.NodeId, nil
4152
}
4253
// Configure default device ID on the switch.
43-
gnmi.Replace(t, d, gnmi.OC().Component(icName).IntegratedCircuit().NodeId().Config(), defaultDeviceID)
54+
_, err = ygnmi.Replace(ctx, yc, gnmi.OC().Component(icName).IntegratedCircuit().NodeId().Config(), defaultDeviceID)
55+
if err != nil {
56+
return 0, fmt.Errorf("failed to configure default device ID, err: %v", err)
57+
}
4458
// Verify that default device ID has been configured and return that.
45-
if got, want := gnmi.Get(t, d, gnmi.OC().Component(icName).IntegratedCircuit().NodeId().State()), defaultDeviceID; got != want {
46-
return 0, errors.Errorf("failed to configure default device ID")
59+
devID, err := ygnmi.Await(ctx, yc, gnmi.OC().Component(icName).IntegratedCircuit().NodeId().State(), defaultDeviceID, nil)
60+
if err != nil {
61+
return 0, fmt.Errorf("waiting for device ID to be %v failed, have %v, err: %v", defaultDeviceID, devID.String(), err)
4762
}
4863
return defaultDeviceID, nil
4964
}

0 commit comments

Comments
 (0)