-
Notifications
You must be signed in to change notification settings - Fork 17.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
testing/synctest: add experimental synctest package
The testing/synctest package is experimental, subject to change or removal, and only present when GOEXPERIMENT=synctest. Fixes #69687 Change-Id: I6c79e7d1479a54bebcd2de754854c87bfd0a5fa1 Reviewed-on: https://go-review.googlesource.com/c/go/+/629735 Reviewed-by: Michael Pratt <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
- Loading branch information
Showing
4 changed files
with
74 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// Copyright 2024 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
//go:build goexperiment.synctest | ||
|
||
// Package synctest provides support for testing concurrent code. | ||
// | ||
// This package only exists when using Go compiled with GOEXPERIMENT=synctest. | ||
// It is experimental, and not subject to the Go 1 compatibility promise. | ||
package synctest | ||
|
||
import ( | ||
"internal/synctest" | ||
) | ||
|
||
// Run executes f in a new goroutine. | ||
// | ||
// The new goroutine and any goroutines transitively started by it form | ||
// an isolated "bubble". | ||
// Run waits for all goroutines in the bubble to exit before returning. | ||
// | ||
// Goroutines in the bubble use a synthetic time implementation. | ||
// The initial time is midnight UTC 2000-01-01. | ||
// | ||
// Time advances when every goroutine in the bubble is blocked. | ||
// For example, a call to time.Sleep will block until all other | ||
// goroutines are blocked and return after the bubble's clock has | ||
// advanced. See [Wait] for the specific definition of blocked. | ||
// | ||
// If every goroutine is blocked and there are no timers scheduled, | ||
// Run panics. | ||
// | ||
// Channels, time.Timers, and time.Tickers created within the bubble | ||
// are associated with it. Operating on a bubbled channel, timer, or ticker | ||
// from outside the bubble panics. | ||
func Run(f func()) { | ||
synctest.Run(f) | ||
} | ||
|
||
// Wait blocks until every goroutine within the current bubble, | ||
// other than the current goroutine, is durably blocked. | ||
// It panics if called from a non-bubbled goroutine, | ||
// or if two goroutines in the same bubble call Wait at the same time. | ||
// | ||
// A goroutine is durably blocked if can only be unblocked by another | ||
// goroutine in its bubble. The following operations durably block | ||
// a goroutine: | ||
// - a send or receive on a channel from within the bubble | ||
// - a select statement where every case is a channel within the bubble | ||
// - sync.Cond.Wait | ||
// - time.Sleep | ||
// | ||
// A goroutine executing a system call or waiting for an external event | ||
// such as a network operation is not durably blocked. | ||
// For example, a goroutine blocked reading from an network connection | ||
// is not durably blocked even if no data is currently available on the | ||
// connection, because it may be unblocked by data written from outside | ||
// the bubble or may be in the process of receiving data from a kernel | ||
// network buffer. | ||
// | ||
// A goroutine is not durably blocked when blocked on a send or receive | ||
// on a channel that was not created within its bubble, because it may | ||
// be unblocked by a channel receive or send from outside its bubble. | ||
func Wait() { | ||
synctest.Wait() | ||
} |