Source file src/testing/synctest/context_example_test.go
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 } 79