<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
example_test.go,展示了With-系列的4個例子
func ExampleWithCancel() { gen := func(ctx context.Context) <-chan int { dst := make(chan int) n := 1 go func() { for { select { case <-ctx.Done(): return // returning not to leak the goroutine case dst <- n: n++ } } }() return dst } ctx, cancel := context.WithCancel(context.Background()) defer cancel() // cancel when we are finished consuming integers for n := range gen(ctx) { fmt.Println(n) if n == 5 { break } } // Output: // 1 // 2 // 3 // 4 // 5 }
結構分析,gen
是一個函數,返回值是一個通道, for range channel
是有特殊意義的, for會迴圈從channel讀資料,直到channel被close(),不然就是無限迴圈.
gen內部的協程就是典型的閉包,for range會不斷觸發讀,gen內部的for select 會不斷觸發寫,主協程讀5次之後,會結束main函數,會觸發defer函數, 也就是取消操作對應的回撥,此時done通道會被close,gen內部的協程會正常退出.
這個例子是測試支援取消訊號的上下文,取消函數的呼叫放在了main
的defer
函數中.
const shortDuration = 1 * time.Millisecond func ExampleWithDeadline() { d := time.Now().Add(shortDuration) ctx, cancel := context.WithDeadline(context.Background(), d) // Even though ctx will be expired, it is good practice to call its // cancellation function in any case. Failure to do so may keep the // context and its parent alive longer than necessary. defer cancel() select { case <-time.After(1 * time.Second): fmt.Println("overslept") case <-ctx.Done(): fmt.Println(ctx.Err()) } // Output: // context deadline exceeded }
deadline
的這個例子,在main
的defer
中也有主動呼叫取消函數的. 實際上通過列印可以顯示deadline是否按預期工作.
func ExampleWithTimeout() { ctx, cancel := context.WithTimeout(context.Background(), shortDuration) defer cancel() select { case <-time.After(1 * time.Second): fmt.Println("overslept") case <-ctx.Done(): fmt.Println(ctx.Err()) // prints "context deadline exceeded" } // Output: // context deadline exceeded }
timeout
只是deadline
的一種簡寫.
func ExampleWithValue() { type favContextKey string f := func(ctx context.Context, k favContextKey) { if v := ctx.Value(k); v != nil { fmt.Println("found value:", v) return } fmt.Println("key not found:", k) } k := favContextKey("language") ctx := context.WithValue(context.Background(), k, "Go") f(ctx, k) f(ctx, favContextKey("color")) // Output: // found value: Go // key not found: color }
context.WithValue
和Context.Value()
是存取操作, 取的時候,如果key沒找到,會返回nil.
context_text.go,x_test.go
是單元測試, example_test.go
是範例,benchmark_test.go是基準測試, net_test.go展示了deadline對net包的支援.
先看單元測試的context_text.go.
type testingT interface {} type otherContext struct {} func quiescent(t testingT) time.Duration {} func XTestBackground(t testingT) {} func XTestTODO(t testingT) {} func XTestWithCancel(t testingT) {} func contains(m map[canceler]struct{}, key canceler) bool {} func XTestParentFinishesChild(t testingT) {} func XTestChildFinishesFirst(t testingT) {} func testDeadline(c Context, name string, t testingT) {} func XTestDeadline(t testingT) {} func XTestTimeout(t testingT) {} func XTestCanceledTimeout(t testingT) {} func XTestValues(t testingT) {} func XTestAllocs(t testingT, testingShort func() bool, testingAllocsPerRun func(int, func()) float64) {} func XTestSimultaneousCancels(t testingT) {} func XTestInterlockedCancels(t testingT) {} func XTestLayersCancel(t testingT) {} func XTestLayersTimeout(t testingT) {} func XTestCancelRemoves(t testingT) {} func XTestWithCancelCanceledParent(t testingT) {} func XTestWithValueChecksKey(t testingT) {} func XTestInvalidDerivedFail(t testingT) {} func recoveredValue(fn func()) (v interface{}) {} func XTestDeadlineExceededSupportsTimeout(t testingT) {} type myCtx struct {} type myDoneCtx struct {} func (d *myDoneCtx) Done() <-chan struct{} {} func XTestCustomContextGoroutines(t testingT) {}
這暴露的大多測試函數的引數型別是testingT介面型別,但這個原始檔中沒有實現testingT
介面的,
func TestBackground(t *testing.T) { XTestBackground(t) } func TestTODO(t *testing.T) { XTestTODO(t) } func TestWithCancel(t *testing.T) { XTestWithCancel(t) } func TestParentFinishesChild(t *testing.T) { XTestParentFinishesChild(t) } func TestChildFinishesFirst(t *testing.T) { XTestChildFinishesFirst(t) } func TestDeadline(t *testing.T) { XTestDeadline(t) } func TestTimeout(t *testing.T) { XTestTimeout(t) } func TestCanceledTimeout(t *testing.T) { XTestCanceledTimeout(t) } func TestValues(t *testing.T) { XTestValues(t) } func TestAllocs(t *testing.T) { XTestAllocs(t, testing.Short, testing.AllocsPerRun) } func TestSimultaneousCancels(t *testing.T) { XTestSimultaneousCancels(t) } func TestInterlockedCancels(t *testing.T) { XTestInterlockedCancels(t) } func TestLayersCancel(t *testing.T) { XTestLayersCancel(t) } func TestLayersTimeout(t *testing.T) { XTestLayersTimeout(t) } func TestCancelRemoves(t *testing.T) { XTestCancelRemoves(t) } func TestWithCancelCanceledParent(t *testing.T) { XTestWithCancelCanceledParent(t) } func TestWithValueChecksKey(t *testing.T) { XTestWithValueChecksKey(t) } func TestInvalidDerivedFail(t *testing.T) { XTestInvalidDerivedFail(t) } func TestDeadlineExceededSupportsTimeout(t *testing.T) { XTestDeadlineExceededSupportsTimeout(t) } func TestCustomContextGoroutines(t *testing.T) { XTestCustomContextGoroutines(t) }
這是x_test.go
的內容,直接是用testing.T
型別來實現testingT介面.
那先分析一下testing.T對testingT介面的實現.
type T struct { common isParallel bool context *testContext } func (t *T) Deadline() (deadline time.Time, ok bool) { deadline = t.context.deadline return deadline, !deadline.IsZero() }
注意:testing.T.context不是context.Context的實現型別, Deadline()返回了t.context中儲存的deadline資訊.
testing.T內嵌了testing.common,大部分方法集都來至common:
Error(args ...interface{}) Errorf(format string, args ...interface{}) Fail() FailNow() Failed() bool Fatal(args ...interface{}) Fatalf(format string, args ...interface{}) Helper() Log(args ...interface{}) Logf(format string, args ...interface{}) Name() string Skip(args ...interface{}) SkipNow() Skipf(format string, args ...interface{}) Skipped() bool
Parallel()
是由testing.T
實現,某個測試用例多次重複執行時, 可啟用並行引數.
到此這篇關於Go語言context test原始碼分析詳情的文章就介紹到這了,更多相關Go語言context test原始碼分析內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45