feat: tlsping and tcpping using step-by-step (#815)
## Checklist - [x] I have read the [contribution guidelines](https://github.com/ooni/probe-cli/blob/master/CONTRIBUTING.md) - [x] reference issue for this pull request: https://github.com/ooni/probe/issues/2158 - [x] if you changed anything related how experiments work and you need to reflect these changes in the ooni/spec repository, please link to the related ooni/spec pull request: https://github.com/ooni/spec/pull/250 ## Description This diff refactors the codebase to reimplement tlsping and tcpping to use the step-by-step measurements style. See docs/design/dd-003-step-by-step.md for more information on the step-by-step measurement style.
This commit is contained in:
parent
5371c7f486
commit
5ebdeb56ca
48 changed files with 2825 additions and 299 deletions
48
internal/testingx/time.go
Normal file
48
internal/testingx/time.go
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
package testingx
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TimeDeterministic implements time.Now in a deterministic fashion
|
||||
// such that every time.Time call returns a moment in time that occurs
|
||||
// one second after the configured zeroTime.
|
||||
//
|
||||
// It's safe to use this struct from multiple goroutine contexts.
|
||||
type TimeDeterministic struct {
|
||||
// counter counts the number of "ticks" passed since the zero time: each
|
||||
// call to Now increments this counter by one second.
|
||||
counter time.Duration
|
||||
|
||||
// mu protects fields in this structure from concurrent access.
|
||||
mu sync.Mutex
|
||||
|
||||
// zeroTime is the lazy-initialized zero time. The first call to Now
|
||||
// will initialize this field with the current time.
|
||||
zeroTime time.Time
|
||||
}
|
||||
|
||||
// NewTimeDeterministic creates a new instance using the given zeroTime value.
|
||||
func NewTimeDeterministic(zeroTime time.Time) *TimeDeterministic {
|
||||
return &TimeDeterministic{
|
||||
counter: 0,
|
||||
mu: sync.Mutex{},
|
||||
zeroTime: zeroTime,
|
||||
}
|
||||
}
|
||||
|
||||
// Now is like time.Now but more deterministic. The first call returns the
|
||||
// configured zeroTime and subsequent calls return moments in time that occur
|
||||
// exactly one second after the time returned by the previous call.
|
||||
func (td *TimeDeterministic) Now() time.Time {
|
||||
td.mu.Lock()
|
||||
if td.zeroTime.IsZero() {
|
||||
td.zeroTime = time.Now()
|
||||
}
|
||||
offset := td.counter
|
||||
td.counter += time.Second
|
||||
res := td.zeroTime.Add(offset)
|
||||
td.mu.Unlock()
|
||||
return res
|
||||
}
|
||||
Loading…
Reference in a new issue