]> Cypherpunks repositories - gostls13.git/commitdiff
testing/synctest: add experimental synctest package
authorDamien Neil <dneil@google.com>
Tue, 19 Nov 2024 18:42:11 +0000 (10:42 -0800)
committerDamien Neil <dneil@google.com>
Wed, 20 Nov 2024 16:26:46 +0000 (16:26 +0000)
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 <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/go/build/deps_test.go
src/internal/goexperiment/flags.go
src/internal/synctest/synctest.go
src/testing/synctest/synctest.go [new file with mode: 0644]

index 365efa7e2568c94a831abeaf043851502a2faf50..58504ed7daabbe04610b2b00578651e12ad453d2 100644 (file)
@@ -650,7 +650,8 @@ var depsRules = `
        < testing;
 
        RUNTIME
-       < internal/synctest;
+       < internal/synctest
+       < testing/synctest;
 
        log/slog, testing
        < testing/slogtest;
index e654471a6a28e61bf84af5b63301905533e75b2d..31b3d0315b64f8e30f1e8d0ecca54852428ddb53 100644 (file)
@@ -125,4 +125,7 @@ type Flags struct {
 
        // SyncHashTrieMap enables the HashTrieMap sync.Map implementation.
        SyncHashTrieMap bool
+
+       // Synctest enables the testing/synctest package.
+       Synctest bool
 }
index eb317fbf82f76d887b93fb93048b2b4762a899f0..7714a82bf495470da80d8c0be27e549c172de4ee 100644 (file)
@@ -3,60 +3,16 @@
 // license that can be found in the LICENSE file.
 
 // Package synctest provides support for testing concurrent code.
+//
+// See the testing/synctest package for function documentation.
 package synctest
 
 import (
        _ "unsafe" // for go:linkname
 )
 
-// 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.
-//
 //go:linkname Run
 func Run(f func())
 
-// 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.
-//
 //go:linkname Wait
 func Wait()
diff --git a/src/testing/synctest/synctest.go b/src/testing/synctest/synctest.go
new file mode 100644 (file)
index 0000000..90efc78
--- /dev/null
@@ -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()
+}