Skip to content

Commit 39f2032

Browse files
neildgopherbot
authored andcommitted
testing/synctest: add some examples
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>
1 parent b50ccef commit 39f2032

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright 2025 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build goexperiment.synctest
6+
7+
package synctest_test
8+
9+
import (
10+
"context"
11+
"fmt"
12+
"testing/synctest"
13+
"time"
14+
)
15+
16+
// This example demonstrates testing the context.AfterFunc function.
17+
//
18+
// AfterFunc registers a function to execute in a new goroutine
19+
// after a context is canceled.
20+
//
21+
// The test verifies that the function is not run before the context is canceled,
22+
// and is run after the context is canceled.
23+
func Example_contextAfterFunc() {
24+
synctest.Run(func() {
25+
// Create a context.Context which can be canceled.
26+
ctx, cancel := context.WithCancel(context.Background())
27+
28+
// context.AfterFunc registers a function to be called
29+
// when a context is canceled.
30+
afterFuncCalled := false
31+
context.AfterFunc(ctx, func() {
32+
afterFuncCalled = true
33+
})
34+
35+
// The context has not been canceled, so the AfterFunc is not called.
36+
synctest.Wait()
37+
fmt.Printf("before context is canceled: afterFuncCalled=%v\n", afterFuncCalled)
38+
39+
// Cancel the context and wait for the AfterFunc to finish executing.
40+
// Verify that the AfterFunc ran.
41+
cancel()
42+
synctest.Wait()
43+
fmt.Printf("after context is canceled: afterFuncCalled=%v\n", afterFuncCalled)
44+
45+
// Output:
46+
// before context is canceled: afterFuncCalled=false
47+
// after context is canceled: afterFuncCalled=true
48+
})
49+
}
50+
51+
// This example demonstrates testing the context.WithTimeout function.
52+
//
53+
// WithTimeout creates a context which is canceled after a timeout.
54+
//
55+
// The test verifies that the context is not canceled before the timeout expires,
56+
// and is canceled after the timeout expires.
57+
func Example_contextWithTimeout() {
58+
synctest.Run(func() {
59+
// Create a context.Context which is canceled after a timeout.
60+
const timeout = 5 * time.Second
61+
ctx, cancel := context.WithTimeout(context.Background(), timeout)
62+
defer cancel()
63+
64+
// Wait just less than the timeout.
65+
time.Sleep(timeout - time.Nanosecond)
66+
synctest.Wait()
67+
fmt.Printf("before timeout: ctx.Err() = %v\n", ctx.Err())
68+
69+
// Wait the rest of the way until the timeout.
70+
time.Sleep(time.Nanosecond)
71+
synctest.Wait()
72+
fmt.Printf("after timeout: ctx.Err() = %v\n", ctx.Err())
73+
74+
// Output:
75+
// before timeout: ctx.Err() = <nil>
76+
// after timeout: ctx.Err() = context deadline exceeded
77+
})
78+
}

0 commit comments

Comments
 (0)