Intermittent failures
Pages 44
- Home
- API best practices
- Azure provider design implementation notes
- Blocking bugs
- Bootstrap Internals (WIP)
- Boring Techniques
- Bug fixes and patching
- CI Tests
- Code Review Checklists
- Containers
- Creating New Repos
- Debugging Juju
- Debugging Juju Misc Topics Pointers
- Debugging Races
- Diagnosing MongoDB Performance
- Faster LXD
- Feature Documentation
- Getting Mongo dump
- Guidelines for writing workers
- Hacking upload tools
- howto: implement effective config structs
- Implementing environment providers
- Incomplete Transactions and MgoPurge
- Interactive Commands
- Intermittent failures
- Juju Logging
- Juju Scripts
- Juju Storage (WIP)
- Juju User Documentation
- KVM instance creation
- Login into MongoDB
- Managing complexity
- mgo txn example
- MgoPurgeTool
- Misc Topics
- Mongo Issues
- MongoDB and Consistency
- pprof facility
- Reviewboard Tips and Tricks
- Stop Start Machine Agent
- Stress Test
- Triaging Bugs
- Update Launchpad Dependency
- Writing Unit Tests
- Show 29 more pages…
Navigation
Testing
Releases
Documentation
Development
- READ BEFORE CODING
- Blocking bugs process
- Bug fixes and patching
- Contributing
- Code Review Checklists
- Creating New Repos
-
MongoDB and Consistency
- [mgo/txn Example] (https://github.com/juju/juju/wiki/mgo-txn-example)
- Scripts
- Update Launchpad Dependency
- Writing workers
- Reviewboard Tips
Debugging and QA
- Debugging Juju
- [Faster LXD] (https://github.com/juju/juju/wiki/Faster-LXD)
Clone this wiki locally
NB: This page is linked to from an error message logged in github.com/juju/testing/clock.go.
testing.Clock
While working on lp:1607044 at the September 2016 quality sprint we determined that there are some timing issues when advancing a clock concurrently with relying on it for timing.
To fix this we've added a clock.WaitAdvance method. This method simply waits until there is something in clock.waiting before advancing. In the case of a happy (common, expected) path, this doesn't wait at all. Only in the case of the unhappy (unexpected, rare) path does it pause to allow clock.waiting to be populated.
To help suss out other cases where this behavior might cause intermittent failures clock.Advance now logs an entry if it is advancing a clock with an empty clock.waiting slice.
To illustrate the issue in the linked bug we've outlined the happy and unhappy paths in the following ASCII diagrams.
Happy path
Test creates and starts a
/ worker, https://goo.gl/LQNepS
|
| clock.Advance(duration) https://goo.gl/hbpAvp
/ / moves time forward.
| |
| |
| |
| |
| | Happy clock.Advance called
| | / second, clock.waiting conatains
| | | alarm
| | | Test passes
| | / /
|-----+-------+-----+-----+-------+---------+--+------+----->
| | | \
| | | Worker receives struct on channel
| | | calls worker function
| | \_worker select loop now
| | listens on channel with real
| | delay: https://goo.gl/RHlfVC
| |
| \_first run through loop has zero delay and
| immediately fires https://goo.gl/FbJ3KD
|
worker sets up a select
loop https://goo.gl/FbJ3KD
listening on <-clock.After(delay)
Unhappy path
Test creates and starts a
/ worker, https://goo.gl/LQNepS
|
| clock.Advance(duration) https://goo.gl/hbpAvp
/ / moves time forward.
| |
| |
| |
| |
| | Unhappy path clock.Advance happens first
| | / So nothing in clock.waiting when alarms
| | | notified.
| | | Test times out.
| | / /
|-----+-------+-----+-----+-------+------+-------+-------+------->
| | | \
| | | worker continues waiting on select
| | |
| | \ worker select loop now
| | listens on channel with real
| | delay: https://goo.gl/RHlfVC
| |
| \_first run through loop has zero delay and
| immediately fires https://goo.gl/FbJ3KD
|
worker sets up a select
loop https://goo.gl/FbJ3KD
listening on <-clock.After(delay)