Skip to content

Commit

Permalink
Do not suspend DPC testing when clocks are not synchronized
Browse files Browse the repository at this point in the history
If DPC is failing connectivity tests (due to some transient network
issue) and device is powered off for long enough that clocks loose time
(or there is no battery to keep them running), device will not be able
to establish connectivity after power on for a very long time.
This is because we demand that failed DPC is tried again only after
some time elapses (5 minutes) since the last failed connectivity test.
However, when device starts with clocks reset at time "zero"
(i.e. start of the epoch), it will take many decades until the current
time (as reported by clocks) is past the last failure timestamp.
The solution is to detect unsync clocks and allow to test and use DPC
immediately.

Signed-off-by: Milan Lenco <milan@zededa.com>
(cherry picked from commit b3bdbc6)
  • Loading branch information
milan-zededa committed Sep 19, 2023
1 parent 36c5e64 commit 0e50dd6
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 16 deletions.
8 changes: 8 additions & 0 deletions pkg/pillar/types/zedroutertypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,14 @@ func (config DevicePortConfig) IsDPCTestable(minTimeSinceFailure time.Duration)
if config.LastSucceeded.After(config.LastFailed) {
return true
}
if config.LastFailed.After(time.Now()) {
// Clocks are not in sync - most likely they are still around
// the start of the epoch.
// Network is likely needed to synchronize the clocks using NTP,
// and we should attempt to establish network connectivity using
// any DPC available.
return true
}
return time.Since(config.LastFailed) >= minTimeSinceFailure
}

Expand Down
51 changes: 35 additions & 16 deletions pkg/pillar/types/zedroutertypes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,56 +183,75 @@ func TestIsDPCUsable(t *testing.T) {
}

func TestIsDPCTestable(t *testing.T) {
n := time.Now()
testMatrix := map[string]struct {
devicePortConfig DevicePortConfig
expectedValue bool
}{
"Difference is exactly 60 seconds": {
"DPC always failed test and not enough time passed since the last test": {
devicePortConfig: DevicePortConfig{
TestResults: TestResults{
LastFailed: n.Add(time.Second * 60),
LastSucceeded: n,
LastFailed: time.Now().Add(-2 * time.Minute),
LastSucceeded: time.Time{},
},
Ports: usablePorts,
},
expectedValue: false,
},
"Difference is 61 seconds": {
"DPC succeeded, then failed and not enough time passed since then": {
devicePortConfig: DevicePortConfig{
TestResults: TestResults{
LastFailed: n.Add(time.Second * 61),
LastSucceeded: n,
LastFailed: time.Now().Add(-2 * time.Minute),
LastSucceeded: time.Now().Add(-4 * time.Minute),
},
Ports: usablePorts,
},
expectedValue: false,
},
"Difference is 59 seconds": {
"DPC always failed test but enough time passed since the last test": {
devicePortConfig: DevicePortConfig{
TestResults: TestResults{
LastFailed: n.Add(time.Second * 59),
LastSucceeded: n,
LastFailed: time.Now().Add(-6 * time.Minute),
LastSucceeded: time.Time{},
},
Ports: usablePorts,
},
expectedValue: false,
expectedValue: true,
},
"LastFailed is 0": {
"DPC succeeded, then failed but enough time passed since then": {
devicePortConfig: DevicePortConfig{
TestResults: TestResults{
LastFailed: time.Now().Add(-6 * time.Minute),
LastSucceeded: time.Now().Add(-8 * time.Minute),
},
Ports: usablePorts,
},
expectedValue: true,
},
"DPC always succeeded test": {
devicePortConfig: DevicePortConfig{
TestResults: TestResults{
LastFailed: time.Time{},
LastSucceeded: n,
LastSucceeded: time.Now().Add(-2 * time.Minute),
},
Ports: usablePorts,
},
expectedValue: true,
},
"Last Succeeded is after Last Failed": {
"DPC failed but later succeeded test": {
devicePortConfig: DevicePortConfig{
TestResults: TestResults{
LastFailed: n,
LastSucceeded: n.Add(time.Second * 61),
LastFailed: time.Now().Add(-4 * time.Minute),
LastSucceeded: time.Now().Add(-2 * time.Minute),
},
Ports: usablePorts,
},
expectedValue: true,
},
"Clocks are not synchronized": {
devicePortConfig: DevicePortConfig{
TestResults: TestResults{
LastFailed: time.Now().Add(time.Hour),
LastSucceeded: time.Time{},
},
Ports: usablePorts,
},
Expand Down

0 comments on commit 0e50dd6

Please sign in to comment.