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  

View as plain text