// 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() }