]> Cypherpunks repositories - gostls13.git/commitdiff
testing/synctest: add some examples
authorDamien Neil <dneil@google.com>
Tue, 7 Jan 2025 22:29:23 +0000 (14:29 -0800)
committerGopher Robot <gobot@golang.org>
Wed, 8 Jan 2025 04:05:28 +0000 (20:05 -0800)
For #67434

Change-Id: Iebcfc2559a62405fea7e3ceff8cf6c2f50b61def
Reviewed-on: https://go-review.googlesource.com/c/go/+/641176
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Damien Neil <dneil@google.com>

src/testing/synctest/context_example_test.go [new file with mode: 0644]

diff --git a/src/testing/synctest/context_example_test.go b/src/testing/synctest/context_example_test.go
new file mode 100644 (file)
index 0000000..5f7205e
--- /dev/null
@@ -0,0 +1,78 @@
+// Copyright 2025 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_test
+
+import (
+       "context"
+       "fmt"
+       "testing/synctest"
+       "time"
+)
+
+// This example demonstrates testing the context.AfterFunc function.
+//
+// AfterFunc registers a function to execute in a new goroutine
+// after a context is canceled.
+//
+// The test verifies that the function is not run before the context is canceled,
+// and is run after the context is canceled.
+func Example_contextAfterFunc() {
+       synctest.Run(func() {
+               // Create a context.Context which can be canceled.
+               ctx, cancel := context.WithCancel(context.Background())
+
+               // context.AfterFunc registers a function to be called
+               // when a context is canceled.
+               afterFuncCalled := false
+               context.AfterFunc(ctx, func() {
+                       afterFuncCalled = true
+               })
+
+               // The context has not been canceled, so the AfterFunc is not called.
+               synctest.Wait()
+               fmt.Printf("before context is canceled: afterFuncCalled=%v\n", afterFuncCalled)
+
+               // Cancel the context and wait for the AfterFunc to finish executing.
+               // Verify that the AfterFunc ran.
+               cancel()
+               synctest.Wait()
+               fmt.Printf("after context is canceled:  afterFuncCalled=%v\n", afterFuncCalled)
+
+               // Output:
+               // before context is canceled: afterFuncCalled=false
+               // after context is canceled:  afterFuncCalled=true
+       })
+}
+
+// This example demonstrates testing the context.WithTimeout function.
+//
+// WithTimeout creates a context which is canceled after a timeout.
+//
+// The test verifies that the context is not canceled before the timeout expires,
+// and is canceled after the timeout expires.
+func Example_contextWithTimeout() {
+       synctest.Run(func() {
+               // Create a context.Context which is canceled after a timeout.
+               const timeout = 5 * time.Second
+               ctx, cancel := context.WithTimeout(context.Background(), timeout)
+               defer cancel()
+
+               // Wait just less than the timeout.
+               time.Sleep(timeout - time.Nanosecond)
+               synctest.Wait()
+               fmt.Printf("before timeout: ctx.Err() = %v\n", ctx.Err())
+
+               // Wait the rest of the way until the timeout.
+               time.Sleep(time.Nanosecond)
+               synctest.Wait()
+               fmt.Printf("after timeout:  ctx.Err() = %v\n", ctx.Err())
+
+               // Output:
+               // before timeout: ctx.Err() = <nil>
+               // after timeout:  ctx.Err() = context deadline exceeded
+       })
+}