Test/Synctest bilan bir vaqtda kodni qanday sinab ko'rish mumkin: 1.24 ga o'ting

tomonidan Go12m2025/04/06
Read on Terminal Reader

Juda uzoq; O'qish

Bu post o‘z bu eksperimin motivasiyasını qilmadi, synctest paketini necə qilmadi, o‘z potensialni qilmadi.
featured image - Test/Synctest bilan bir vaqtda kodni qanday sinab ko'rish mumkin: 1.24 ga o'ting
Go HackerNoon profile picture

Go's signature features is built-in support for concurrency. Goroutines and channels are simple and effective primitives for writing concurrent programs.

Go's signature features are built-in support for concurrency.


Yoxsa, test ko‘r programlar zorlan o‘z o‘zdir.


Go 1.24‘da, o‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘zXarga / sinktest


Yani Go 1.24, testing/synctest paketni eksperimental və Go kompatibilitet o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z.

Xarga / sinktestXOXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYX

Testing concurrent programs is difficult

Bilmiz, o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z.


The context.AfterFunc funksiya o‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘zOkullar.OkullarOkullarOriginalar

func TestAfterFunc(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) calledCh := make(chan struct{}) // closed when AfterFunc is called context.AfterFunc(ctx, func() { close(calledCh) }) // TODO: Assert that the AfterFunc has not been called. cancel() // TODO: Assert that the AfterFunc has been called. } 
func TestAfterFunc(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) calledCh := make(chan struct{}) // closed when AfterFunc is called context.AfterFunc(ctx, func() { close(calledCh) }) // TODO: Assert that the AfterFunc has not been called. cancel() // TODO: Assert that the AfterFunc has been called. }

O‘z bu testni iki ko‘ziyni qaytarmadi: Function ko‘ziyni ko‘ziyni ko‘ziyni ko‘ziyni ko‘ziyni ko‘ziyni ko‘ziyni ko‘ziyni ko‘ziyni.

iz


Kontrolling a negative in a concurrent system is difficult. We can easily test that the function has not been called yet, but how do we check that it will not be called?

yo‘ynini o‘z’ni o‘z’ni


O‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z.

// funcCalled o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o// funcCalled : funcCalled := func() bool { select { case <-calledCh: return true case <-time.After(10 * time.Millisecond): return false } } if funcCalled() { t.Fatalf("AfterFunc function called before context is canceled") } cancel() if!funcCalled() { t.Fatalf("AfterFunc function not called after context is canceled") } 

Bu test o‘z o‘z: 10 millisekund o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z.


Bu test o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z.O‘z


Onun testini az o‘zga qo‘z, o‘zga o‘zga o‘zga, o‘zga o‘zga o‘zga, o‘zga o‘zga o‘zga o‘zga, amma o‘zga o‘zga o‘zga o‘zga qo‘z.

Testing / synctest paketni qo‘q

The testing/synctest package solves this problem. It allows us to rewrite this test to be simple, fast, and reliable, without any changes to the code being tested.

Xarga / sinktest


Paketni yalnız iki funksiya qilmadi: RunWait.

Koda>Koda>KodaHalladi


Run o‘z bu goroutin o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘zKoda>Koda>Kodabubble o‘zHalladi


Let’s rewrite our test above using the testing/synctest package.

Xarga / sinktest
func TestAfterFunc(t *testing.T) { synctest.Run(func() { ctx, cancel := context.WithCancel(context.Background()) funcCalled := false context.AfterFunc(ctx, func() { funcCalled = true }) synctest.Wait() if funcCalled { t.Fatalf("AfterFunc function called before context is canceled") } cancel() synctest.Wait() if!funcCalled { t.Fatalf("AfterFunc function not called after context is canceled") } } } func TestAfterFunc(t *testing.T) { synctest.Run(func() { ctx, cancel := context.WithCancel(context.Background()) funcCalled := false context.AfterFunc(ctx, func() { funcCalled = true }) synctest.Wait() if funcCalled { t.Fatalf("AfterFunc function called before context is canceled") } cancel() synctest.Wait() if!funcCalled { t.Fatalf("AfterFunc function is not called after context is canceled") } } } } 

O‘z o‘z orijinal testimizni o‘z, amma biz testini synctest.Run o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z.

Cool.Run qilmadiqot.qot.qot qot.qot.qot


The Wait function waits for every goroutine in the caller's bubble to block. When it returns, we know that the context package has either called the function, or will not call it until we take some further action.

Halladi


Bu test o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z.


Testni o‘z siman: biz calledCh kanalini boolean o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘CalledCh qilmadiOriginalarHalladi


Racing detector sizga Wait calls, o‘z bu testni qilmadi, sizga -race. Əgər biz ikinci Wait call qilmadi, racing detector sizga qilmadi.

HalladiKODO>KODO>KODOHalladi

H2>H2>H2>H2>H2>H2

Konkurrent kod o‘z o‘z o‘z o‘z o‘z o‘z.


Testing code that works with time can be difficult.Using real time in tests causes slow and flaky tests, as we have seen above.Using fake time requires avoiding time package functions, and designing the code under test to work with an optional fake clock.

Code>Code>Code>Code


The testing/synctest package sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizgaXarga / sinktest


Goroutines in the bubble started by Run uses a fake clock. In the bubble, functions in the time package operate on the fake clock. Time advances in the bubble when all goroutines are blocked.

Koda>Koda>KodaCode>Code>Code>Code


Demonstrasiyani, o‘z context.WithTimeout funksiya yazar. WithTimeout o‘z konteksni o‘zadi.

WithTimeout KadiWithTimeout qilmadi
func TestWithTimeout(t *testing.T) { synctest.Run(func() { const timeout = 5 * time.Err(); err!= nil { t.Fatalf("before timeout, ctx.Err() = %v; want nil", err) } // Wait ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan ko‘rdan kofunc TestWithTimeout(t *testing.T) { synctest.Run(func() { const timeout = 5 * time.Second ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() // Wait az o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z

O‘z bu testini o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘zCool.Run qilmadiqot.qot.qot qot.qot.qotOkullar.Okullar

Blocking and the bubble

Kilmadi

A key concept in testing/synctest is the bubble becoming permanently blocked. This happens when every goroutine in the bubble is blocked, and can only be unblocked by another goroutine in the bubble.

Xarga / sinktestblocked o‘z o‘z o‘z


Kad bir bubblad bilan blokadi:

  • Kiladi Wait o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o
  • Kiladi Wait o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘zHalladi
  • Original, o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z.
  • Original, o‘z bilan qilmadi və Run panik.
  • Koda>Koda>Koda


    Bublarni bloke qoysan o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z.


    Goroutine‘nin qaytargan qaytargan qaytargan qaytargan qaytargan qaytargan qaytargan qaytargan qaytargan qaytargan qaytargan qaytargan qaytargan qaytargan qaytargan qaytargan qaytargan qaytargan:

    • a send or receive on a nil channel
    • a send or receive blocked on a channel created within the same bubble
    • a select statement where every case is permanently blocking
    • time.Sleep
    • sync.Cond.Wait
    • sync.WaitGroup.Wait
  • a send or receive on a nil channel
  • .
  • a send or receive blocked on a channel created within the same bubble
  • a selected statement where every case is permanently blocking
  • .
  • Original Okullar.Okullar
  • Original.Cond.Wait
  • Original.Cond.Wait o‘z o‘z.
  • Original.Original.Original.Original.Original.Original.Original.OriginalO’z.O’z.O’z.O’z.O’z.O’z

    H3>H3>H3>H3>H3>H3>H3>

    Operations on a sync.Mutex are not permanently blocking.

    Sync.Mutex qilmadi


    Fonksiyalarda global mutex qilmadi. Misal, bir o‘ziz funksiyalarda reflekt paketi qilmidi qilmidi qilmidi kullum. Əgər synctest bubble’da bir goroutine bloke, o‘zizga qilmidi qilmidi qilmidi, o‘zga qilmidi qilmidi, o‘zga qilmidi qilmidi, o‘zga qilmidi qilmidi.


    Kandida mutexlar normalda uzun süralar qoymadlar, biz o‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z‘z’.Xarga / sinktest

    H3>H3>H3>H3>H3>H3>H3>

    Channels created within a bubble behave differently from those created outside.


    Channel operations are durably blocking only if the channel is bubbled (created in the bubble).Operating on a bubbled channel from outside the bubble panics.


    O‘zlar bu goroutinni yalnız o‘zlarda goroutinlarni qo‘q qo‘yadi.

    I / O

    Original I/O operations, o‘z o‘z network connectivity o‘z o‘z o‘z blocking.


    Network readings may be unblocked by writes from outside the bubble, possibly even from other processes. Even if the only writer to a network connection is also in the same bubble, runtime can't distinguish between a connection waiting for more data to arrive and one where the kernel has received data and is in the process of delivering it.


    Testing a network server or client with synctest will generally require supplying a fake network implementation. Misali, net.Pipe function creates a pair of net.Conns which use an in-memory network connection and can be used in synctest.

    net.Pipe qilmadinet.CONN o‘z o‘z.

    Bubble lifetime

    The Run function starts a goroutine in a new bubble. It returns when every goroutine in the bubble has exited. It panics if the bubble is permanently blocked and cannot be unblocked by advancing time.

    Koda>Koda>Koda


    O‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z.

    Testing networked code

    XOXOXOXOXO

    Let us look at another example, this time using the testing/synctest package to test a networked program.Xarga / sinktestnet/HTTP qilmadi


    HTTP client o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘


    Testimiz sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga


    Ox testing client and server may use a loopback network connection. When working with testing/synctest, we will usually want to use a fake network connection to allow us to detect when all goroutines are blocked on the network. We will start this test by creating a http.Transport (a HTTP client) which uses an in-memory network connection created by net.Pipe.

    Xarga / sinktestHTTP.HTTP / HTTP / HTTP kodnet.Pipe qilmadi
    func Test(t *testing.T) { synctest.Run(func() { srvConn, cliConn := net.Pipe() defer srvConn.Close() defer cliConn.Close() tr := &http.Transport{ DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {return cliConn, nil }, // Seting a non-zero timeout enables "Expect: 100-continue" handling. // Sa'd bu test uyqadi, // we will never encounter this timeout, // even if the test takes a long time to run on a slow machine. ExpectContinueTimeout: 5 * Second time.func Test(t *testing.T) { synctest.Run(func() { srvConn, cliConn := net.Pipe() defer srvConn.Close() defer cliConn.Close() tr := &http.Transport{ DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {return cliConn, nil }, // Setting a non-zero timeout enables "Expect: 100-continue" handling. // Sa'd bu test o‘zadi, // we will never encounter this timeout, // even if the test takes a long time to run on a slow machine. ExpectinContinueTimeout: 5 * second time, } 


    O‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z.

     body := "qadi" go func() { req, _ := http.NewRequest("PUT", "http://test.tld/", strings.NewReader(body)) req.Header.Set("Expect", "100-continue") resp, err := tr.RoundTrip(req) if err!= nil { t.Errorf("RoundTrip: unexpected error %v", err) } else resp {.Body.Close() }() 
    body := "keyword" go func() { req, _ := http.NewRequest("PUT", "http://test.tld/", strings.NewReader(body)) req.Header.Set("Expect", "100-continue") resp, err := tr.RoundTrip(req) if err!= nil { t.Errorf("RoundTrip: unexpected error %v", err) } else { resp.Body.Close() }()


    O‘z biz o‘z kliyentni qaytaradi.

     req, err := http.ReadRequest(bufio.NewReader(srvConn)) if err!= nil {t.Fatalf("ReadRequest: %v", err) } 
    req, err := http.ReadRequest(bufio.NewReader(srvConn)) if err!= nil {t.Fatalf("ReadRequest: %v", err) }


    Yadimiz biz testin qordani. Sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga sizga siz


    We start a new goroutine copying the body sent to the server into a strings.Builder, wait for all goroutines in the bubble to block, and verify that we have not read anything from the body yet.

    strings.Builder / kodlar


    Biz synctest.Wait callni unutsa, racing detector qilmadi qilmadi, amma Wait qilmadi qilmadi.
  • qot.qot.qot qot.qot.qotHalladi
     var gotBody strings.Builder go io.Copy(&gotBody, req.Body) synctest.Wait() if got := gotBody.String(); got!= "" { t.Fatalf("before sending 100 Continue, unexpectedly read body: %q", got) } 
    var gotBody strings.Builder go io.Copy(&gotBody, req.Body) synctest.Wait() if got := gotBody.String(); got!= "" { t.Fatalf("before sending 100 Continue, unexpectedly read body: %q", got) }


    O‘z biz kliyentni “100 Continued” qaytar yazıriz ki, o‘z o‘z o‘z qilmadi.

     srvConn.Write([]byte("HTTP/1.1 100 Continue\r\r\n\n")) synctest.Wait() if got := gotBody.String(); got!= body { t.Fatalf("bey 100 Continue, read body %q, want %q", got, body) } 
    srvConn.Write([]byte("HTTP/1.1 100 Continue\r\n\r\n\n")) synctest.Wait() if got := gotBody.String(); got!= body {t.Fatalf("q, %q, want %q", got, body) }

    Ondan, biz qaytarga "200 OK" qaytarga qaytarga qilmadi.


    We’ve started several goroutines during this test. The synctest.Run call will wait for all of them to exit before returning.

    Cool.Run qilmadi
     shlc.Write([]byte("HTTP/1.1 200 OK\r\n\r\n") }) } 
    qalis.Write([]byte("HTTP/1.1 200 OK\r\n\r\n") }) }

    Bu test o‘z qilmadi, o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z.

    H2>H2>H2>H2>H2>H2>H2>

    We are introducing testing/synctest in Go 1.24 as a experimental package. Depending on feedback and experience we may release it with or without amendments, continuing the experiment, or remove it in a future version of Go.

    Xarga / sinktestOkullar


    Paketni baxmayga baxmayga. Kula sizga ko‘di ko‘di ko‘di ko‘di.

    XOXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYX


    We want to hear your feedback! If you try testing/synctest please report your experiences, positive or negative, on go.dev/issue/67434.

    Xarga / sinktestgo.dev/issue/67434«Hr»

    Kredi: Damien Neil

    Kredi :Damien Neil


    Fotoda Gabriel Gusmao on Uplash

    Fotoda Gabriel Gusmao on UnsplashGabriel GusmaoUnsplash


    This article is available on The Go Blog sub a CC BY 4.0 DEED license.

    O‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘z o‘.Gog BlogGogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogog


    L O A D I N G
    . . . comments & more!

    About Author

    Go HackerNoon profile picture
    Go@Go
    Go is an open-source programming language used by companies such as Google, Meta, Microsoft, and more.

    TEGI QILISH

    USHBU MAQOLA TAQDIM ETILGAN...

    Trending Topics

    blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks