Gopa firma ruwayninkunamanta hukninqa kuskalla ruwanapaq yanapakuymi. Gorutinakuna chaymanta canalkuna kanku primitivos simples chaymanta efectivos programakuna concurrentes qillqanapaq. Ichaqa, programakuna concurrente pruebayqa sasa kanman chaymanta pantayniyuq kanman. Go 1.24 kaqpi, huk musuq, experimental paquete riqsichichkayku prueba concurrente codigo yanapakuypaq. Kay qillqasqa kay experimento qhipanpi kallpachakuymanta sut'inchanqa, imayna synctest paquete llamk'achiyta rikuchinqa, chaymanta hamuq pacha atikuqninmanta rimanqa. testing/synctest Go 1.24 kaqpi, paquete experimental kaq chaymanta mana Go tupachiy promesa kaqman sujetochu. Manam ñawpaqmantachu rikukun. Chayta llamk'achinaykipaq, churasqawan codigoykita huñuy muyuriqniykipi. testing/synctest GOEXPERIMENT=synctest Concurrente programakunata pruebayqa sasam Qallarinapaq, huk facil ejemplota qhawarisun. llamk'ayqa huk llamk'anata kikin gorutina nisqapi waqyasqa kananpaqmi allichan, huk contexto qullusqa kaptin. Kaypi huk prueba atikuq kaqpaq : context.AfterFunc AfterFunc 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. } Kay pruebapi iskay condicionkunata qhawayta munayku: Ruwayqa mana waqyasqachu manaraq contexto cancelasqa kachkaptin, chaymanta ruwana contexto cancelasqa kaptin. waqyasqa Huk negativo nisqa sistema concurrente nisqapi qhawayqa sasam. Faciltan pruebasunman chay función manaraq waqyasqa , ichaqa ¿imaynatataq qhawarisunman waqyasqa kananta? kasqanmanta mana Huk común ruwayqa huk rato suyaymi manaraq huk suceso mana pasananta tukuchkaspa. Huk yanapakuq ruwayta pruebaykuman riqsichiyta kallpachakusun mayqinchus kayta ruwan. // funcCalled reports whether the function was called. 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") } Kay pruebaqa pisilla: 10 milisegundos mana ancha pachachu, ichaqa achka pruebakunapi yapakun. Kay pruebapas escamayuqmi: 10 milisegundos huk unay pacha huk utqaylla computadora kaqpi, ichaqa mana hukniraychu rikuy pausakuna achka segundos durante kaqpi sistemakuna rakisqa chaymanta llumpay cargayuq kaqpi. CI Pruebata mana ancha llañuta ruwayta atisunmanchu aswan pisita ruwanapaq qullqiwan, chaymanta aswan pisi llañuta ruwayta atiykuman aswan llañu ruway qullqiwan, ichaqa mana usqhayllata ruwayta atiykuchu chaymanta atikuq ruwayta atisunmanchu. Prueba/sinctest paquete nisqamanta riqsichiy paquete kay sasachakuy allichan. Kay pruebata wakmanta qillqayta saqiwanchik, mana sasachu, utqaylla, chaymanta atikuq kananpaq, mana ima tikraypas pruebasqa codigo kaqpi. testing/synctest Paqueteqa iskay llamkanakunallam kachkan: hinaspa . Run Wait huk musuq gorutina kaqpi huk ruwayta waqyan. Kay gorutinapas chaymanta ima gorutinakuna qallarisqapas sapanchasqa pachamamapim kachkanku chaytam nispa sutichanchik . suyan sapa gorutina kunan gorutina burbujapi hark'ananpaq huk gorutina burbujapi. Run burbuja Wait Hawa pruebaykuta wakmanta qillqasun paquete kaqwan. testing/synctest 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") } }) } Kayqa yaqa kaqlla ñawpaq pruebaykuwan, ichaqa pruebata huk pruebapi p'istuyku.Llamayta purichiy chaymanta waqyayku.Suyay manaraq ruwayta waqyasqa kasqanmanta utaq mana waqyasqa kasqanmanta afirmachkaspa. synctest.Run synctest.Wait ruwayqa sapa gorutina waqyaqpa burbujanpi hark'ananpaq suyan. Kutimuptinqa, yachayku contexto paquete icha ruwayta waqyasqa, utaq mana waqyanqachu wakin aswan ruwayta ruwanaykupaq. Wait Kay pruebaqa kunanqa usqhaylla, confiable ima. Pruebaqa aswan sasan, chaymanta: kanalta huk booleanwan tikrarqayku. Ñawpaqta huk kanal llamk'achiyta necesitarqayku mana huk willay carrera prueba gorutina kaqwan gorutina kaqwan, ichaqa ruway kunan chay sincronización qun. calledCh AfterFunc Wait Carrera detectorqa waqyakuykunata hamut'an, kay pruebataq pasakun kaqwan kallpaptin. Sichus iskay kaq waqyayta hurquyku, carrera detector allinta willanqa huk dato carrera pruebapi. Wait -race Wait Prueba tiempo Codigo concurrente nisqa sapa kuti pachamanta riman. Tiempowan llamk'aq código pruebaqa sasa kanman. Chiqa pachata pruebakunapi llamk'achiyqa pruebakuna llasaq chaymanta escamayuq ruwan, imaynachus patamanta rikurqayku. Falso pachata llamk'achiyninqa paquete ruwanakunamanta karunchakuyta munan, chaymanta pruebapi kaq código ruwayta huk akllana llulla relojwan llamk'ananpaq. time paqueteqa aswan sasallawan prueba codigo ruwan mayqinchus pachata llamk'achin. testing/synctest nisqawan qallarisqa burbuja nisqapi gorutinas nisqakunaqa falso reloj nisqatam llamk'achinku. Burbuja ukhupi, paquete kaqpi ruwanakuna llulla reloj kaqpi llamk'anku. Tiempoqa burbujapi ñawpaqman purin llapa gorutinakuna hark’asqa kaptin. Run time Qawachinapaq, huk pruebata qillqasun ruwanapaq. huk contextomanta wawata ruwan, mayqinchus huk qusqa pacha tukukuymanta tukukun. context.WithTimeout WithTimeout func TestWithTimeout(t *testing.T) { synctest.Run(func() { const timeout = 5 * time.Second ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() // Wait just less than the timeout. time.Sleep(timeout - time.Nanosecond) synctest.Wait() if err := ctx.Err(); err != nil { t.Fatalf("before timeout, ctx.Err() = %v; want nil", err) } // Wait the rest of the way until the timeout. time.Sleep(time.Nanosecond) synctest.Wait() if err := ctx.Err(); err != context.DeadlineExceeded { t.Fatalf("after timeout, ctx.Err() = %v; want DeadlineExceeded", err) } }) } Kay pruebataqa chiqap pachawan llamkachkanchikman hinam qillqanchik. Huklla chiqan kayqa prueba ruwayta kaqpi p'istuyku, chaymanta waqyayku.Suyay sapa qhipaman.Puñuy waqyay suyanapaq contexto paquete kaqpa pacha yupayninkuna puriyta tukunanpaq. synctest.Run synctest.Wait time.Sleep Bloqueo y la burbuja Huk llalliq hamut'ay kaqpi kan chay burbuja kay . Kayqa ruwakun sapa gorutina burbujapi hark'asqa kaptin, chaymanta huk gorutina burbujapi kaqlla kichariyta atin. testing/synctest durably hark'asqa Huk burbuja unaypaq hark'asqa kaptin: Sichus huk Pendiente Suyay kan chayqa, kutimun. Wait Mana hina kaqtinqa, pachaqa qatiq kutimanmi ñawparin chaymi huk gorutinata kicharinman, sichus kanman chayqa. Mana chayqa, burbujaqa mana ima ruway atiqmi, mancharikun. Run Huk burbuja mana unaypaq hark'asqachu sichus ima gorutina hark'asqa ichaqa rikch'arichisqa kanman ima sucesowan hawa burbujamanta. Huk gorutinata unayta hark'aq operacionkunap hunt'asqa listanqa: huk apachiy utaq chaskiy huk nil canal nisqapi huk apachiy utaq chaskiy harkasqa huk kanalpi kikin burbuja ukhupi kamasqa huk akllasqa willakuy maypichus sapa caso unaypaq hark’achkan time.Sleep sync.Cond.Wait sync.WaitGroup.Wait Mutexes nisqakuna Huk kaqpi llamk'aykuna.Mutex mana unaypaq hark'achkanchu. sync.Mutex Ruwaykuna huk pachantinpi mutex nisqa rantiyqa comunmi. Ejemplopaq, reflect paquete kaqpi huk yupay ruwanakuna huk mutex kaqwan waqaychasqa pachantinpi waqaychasqa llamk'achinku. Sichus huk gorutina huk sincronización burbuja kaqpi hark'an huk mutex hap'isqa huk gorutina hawa burbuja kaqmanta hapichkaspa, mana unaypaq hark'asqachu —hark'asqa kachkan, ichaqa huk gorutina hawa burbujamanta kicharisqa kanqa. Mutexes aswanta mana unay pachapaq hap'isqa kasqankurayku, 's qhawaymantalla qarquyku. testing/synctest Canales nisqakuna Huk burbuja ukhupi kamasqa kanalkunaqa hawapi kamasqa kanalkunamantaqa hukniraymi purinku. Kanal llamk'aykuna unaypaq hark'achkan sichus kanal burbujayuq (burbujapi kamasqa) kaptinlla. Burbuja hawamanta burbujayuq canalpi llamk’ayqa mancharikun. Kay kamachiykuna huk gorutina unupaq hark'asqa kaqta qhawanku, burbuja ukhupi gorutinas kaqwan rimaspalla. E/S Hawa I/O llamkanakuna, ahinataq llika tinkiymanta ñawiriy, mana unaypaq hark'asqachu. Llika ñawiriykuna mana hark'asqa kanmanchu hawa burbujamanta qillqakunawan, ichapas huk ruwanakunamantapas. Llika tinkiyman sapalla qillqaqpas kikin burbuja kaqpi kaptinpas, purichiy pachaqa manam huk tinkiyta aswan willayta chayamunanta suyaspa chaymanta maypi k'iti willayta chaskisqa chaymanta quypi kachkan chaymanta t'aqayta atinchu. Llika servidor utaq cliente synctest kaqwan pruebayqa tukuypaq huk llulla llika ruwayta quyta munanqa. Ejemplopaq, ruwana huk paris s ruwan mayqinkunachus huk yuyarina ukhupi llika tinkiyta llamk'achinku chaymanta synctest pruebakunapi llamk'achiy atikunku. net.Pipe net.Conn Burbuja kawsay pacha ruwayqa musuq burbujapi gorutina nisqatam qallarichin. Kutimun sapa gorutina burbujapi lluqsiptin. Mancharikun sichus burbuja unaypaq hark’asqa kashan, manataqmi tiempo ñawpaqman purisqanwanqa kichariyta atikunmanchu. Run Sapa gorutina burbujamanta lluqsinanpaq kamachiy manaraq Run kutimuchkaptin, pruebakuna allinta qhawana tiyan ima qhipa gorutinas kaqtapas manaraq tukuchkaspa pichanankupaq. Llikapi kaq codigo pruebaspa Huk rikch'anata qhawasunchik, kay kutipi paquete llamk'achispa huk llika programata pruebapaq. Kay rikch'anapaq, paquetepa 100 Katichiy kutichiypa ruwayninta pruebasaqku. testing/synctest net/http Huk HTTP cliente huk mañakuyta kachaq huk “Suyay: 100-hinalla” umalliqta churayta atin servidorman willananpaq cliente yapasqa willayta apachinanpaq kaqta. Chaymanta servidor kutichinman huk 100 Willayta kutichiywan qatiy mañakuymanta puchuq mañakuypaq, utaq wak estadowan clienteman willananpaq chaymanta chay contenido mana necesitakunchu. Ejemplopaq, huk hatun willañiqita kargaq rantiq kay ruwayta llamk'achinman, sirwiq manaraq kachachkaspa willañiqita chaskiyta munasqanmanta takyachinapaq. Pruebayku chiqaqchanqa huk “Suyay: 100-hinalla” umalliq kachaspa HTTP cliente mana huk mañakuypa ruwayninta apachinchu manaraq sirwiq mañachkaptin, chaymanta 100 qatiy kutichiyta chaskisqanmanta qhipaman willayta apachin. Sapa kuti pruebakuna huk willakuq cliente kaqmanta chaymanta servidor kaqmanta huk loopback llika tinkiyta llamk'achiyta atinku. kaqwan llamk'achkaspa, ichaqa, aswanta huk llulla llika tinkiyta llamk'achiyta munasaqku, mayk'aq llapa gorutinakuna llikapi hark'asqa kasqankuta riqsinaykupaq. Kay prueba qallarisaqku huk (huk HTTP cliente) ruwaspa mayqinchus huk yuyarina ukhupi llika tinkiyta kaqwan ruwasqa llamk'achin. testing/synctest http.Transport net.Pipe 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. // Since the following test does not sleep, // we will never encounter this timeout, // even if the test takes a long time to run on a slow machine. ExpectContinueTimeout: 5 * time.Second, } Kay apaykachanapi mañakuyta apachiyku “Suyay: 100-hinalla” umalliq churasqawan. Mañakuyqa musuq gorutina kaqpi kachasqa, prueba tukukunankama mana tukusqa kasqanrayku. body := "request body" 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() } }() Clientepa apachisqan mañakuy umalliqkunata ñawiriyku. req, err := http.ReadRequest(bufio.NewReader(srvConn)) if err != nil { t.Fatalf("ReadRequest: %v", err) } Kunanqa pruebaq sonqonman chayanchis. Munayku afirmayta chay cliente manaraq apachinqachu mañakuy cuerpota. Musuq gorutinata qallariyku servidorman kachasqa kurkuta huk copiaspa.Rurachiq , suyayku llapa gorutinakuna burbuja kaqpi harkananpaq, chaymanta chiqaqchay manaraq imatapas kurkumanta ñawirisqaykuchu. strings.Builder Sichus waqyayta qunqayku, carrera detector allinta quejakunqa huk dato carreramanta, ichaqa kaqwan kayqa mana imamanta manchachikuq. synctest.Wait Wait 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) } “100 Continuar” kutichiyta clienteman qillqayku chaymanta chiqaqchayku kunan mañakuy kurkuta apachisqanmanta. srvConn.Write([]byte("HTTP/1.1 100 Continue\r\n\r\n")) synctest.Wait() if got := gotBody.String(); got != body { t.Fatalf("after sending 100 Continue, read body %q, want %q", got, body) } Hinaspa tukunanpaq, tukuyku “200 OK” nisqa kutichiyta apachispa mañakuyta tukunaykupaq. Kay pruebapiqa achka gorutinakunatam qallarirqayku. waqyayqa llapa lluqsinankuta suyanqa manaraq kutimuchkaspa. synctest.Run srvConn.Write([]byte("HTTP/1.1 200 OK\r\n\r\n")) }) } Kay pruebaqa mana sasachu mast'arikunman huk ruwaykunata pruebapaq, ahinataq chiqaqchay mañakuy kurku mana kachasqachu sichus sirwiq mana mañanchu, utaq kachasqa sichus sirwiq mana kutichinchu huk pacha tukukuy ukhupi. Experimentopa imayna kasqanmanta Go 1.24 kaqpi kaqmanta riqsichichkayku huk paquete hina. Retroalimentación kaqmanta chaymanta experiencia kaqmanta kacharisunman utaq mana allichaywan, experimentota hinalla ruwayta utaq huk hamuq versión Go kaqmanta hurquyta. testing/synctest experimental Paqueteqa manam ñawpaqmantachu rikukun. Chayta llamk'achinaykipaq, churasqawan codigoykita huñuy muyuriqniykipi. GOEXPERIMENT=synctest ¡Uyariyta munayku yuyayniykikunata! Sichus ruwayta pruebanki , ama hina kaspa willay experienciaykikunata, allin utaq mana allin, kaqpi. testing/synctest go.dev/issue/67434 Qillqasqa: Damien Neil Fotoqa nisqapi Gabriel Gusmaomanta Unsplash Kay qillqasqaqa kaypi tarikun CC BY 4.0 DEED nisqa licenciawan. Chay Go Blog nisqa