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 testing/synctest
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.
Go 1.24 kaqpi, testing/synctest
paquete experimental kaq chaymanta mana Go tupachiy promesa kaqman sujetochu. Manam ñawpaqmantachu rikukun. Chayta llamk'achinaykipaq, GOEXPERIMENT=synctest
churasqawan codigoykita huñuy muyuriqniykipi.
Concurrente programakunata pruebayqa sasam
Qallarinapaq, huk facil ejemplota qhawarisun.
context.AfterFunc
llamk'ayqa huk llamk'anata kikin gorutina nisqapi waqyasqa kananpaqmi allichan, huk contexto qullusqa kaptin. Kaypi huk prueba atikuq AfterFunc
kaqpaq :
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 waqyasqa contexto cancelasqa kaptin.
Huk negativo nisqa sistema concurrente nisqapi qhawayqa sasam. Faciltan pruebasunman chay función manaraq waqyasqa kasqanmanta , ichaqa ¿imaynatataq qhawarisunman mana waqyasqa kananta?
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 CI sistemakuna rakisqa chaymanta llumpay cargayuq kaqpi.
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
testing/synctest
paquete kay sasachakuy allichan. Kay pruebata wakmanta qillqayta saqiwanchik, mana sasachu, utqaylla, chaymanta atikuq kananpaq, mana ima tikraypas pruebasqa codigo kaqpi.
Paqueteqa iskay llamkanakunallam kachkan: Run
hinaspa Wait
.
Run
huk musuq gorutina kaqpi huk ruwayta waqyan. Kay gorutinapas chaymanta ima gorutinakuna qallarisqapas sapanchasqa pachamamapim kachkanku chaytam burbuja nispa sutichanchik . Wait
suyan sapa gorutina kunan gorutina burbujapi hark'ananpaq huk gorutina burbujapi.
Hawa pruebaykuta wakmanta qillqasun testing/synctest
paquete kaqwan.
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 synctest.Run
pruebapi p'istuyku.Llamayta purichiy chaymanta synctest.Wait
waqyayku.Suyay manaraq ruwayta waqyasqa kasqanmanta utaq mana waqyasqa kasqanmanta afirmachkaspa.
Wait
ruwayqa sapa gorutina waqyaqpa burbujanpi hark'ananpaq suyan. Kutimuptinqa, yachayku contexto paquete icha ruwayta waqyasqa, utaq mana waqyanqachu wakin aswan ruwayta ruwanaykupaq.
Kay pruebaqa kunanqa usqhaylla, confiable ima.
Pruebaqa aswan sasan, chaymanta: calledCh
kanalta huk booleanwan tikrarqayku. Ñawpaqta huk kanal llamk'achiyta necesitarqayku mana huk willay carrera prueba gorutina kaqwan AfterFunc
gorutina kaqwan, ichaqa Wait
ruway kunan chay sincronización qun.
Carrera detectorqa Wait
waqyakuykunata hamut'an, kay pruebataq pasakun -race
kaqwan kallpaptin. Sichus iskay kaq Wait
waqyayta hurquyku, carrera detector allinta willanqa huk dato carrera pruebapi.
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 time
paquete ruwanakunamanta karunchakuyta munan, chaymanta pruebapi kaq código ruwayta huk akllana llulla relojwan llamk'ananpaq.
testing/synctest
paqueteqa aswan sasallawan prueba codigo ruwan mayqinchus pachata llamk'achin.
Run
nisqawan qallarisqa burbuja nisqapi gorutinas nisqakunaqa falso reloj nisqatam llamk'achinku. Burbuja ukhupi, time
paquete kaqpi ruwanakuna llulla reloj kaqpi llamk'anku. Tiempoqa burbujapi ñawpaqman purin llapa gorutinakuna hark’asqa kaptin.
Qawachinapaq, huk pruebata qillqasun context.WithTimeout
ruwanapaq. WithTimeout
huk contextomanta wawata ruwan, mayqinchus huk qusqa pacha tukukuymanta tukukun.
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 synctest.Run
kaqpi p'istuyku, chaymanta synctest.Wait
waqyayku.Suyay sapa time.Sleep
qhipaman.Puñuy waqyay suyanapaq contexto paquete kaqpa pacha yupayninkuna puriyta tukunanpaq.
Bloqueo y la burbuja
Huk llalliq hamut'ay testing/synctest
kaqpi kan chay burbuja durably hark'asqa kay . Kayqa ruwakun sapa gorutina burbujapi hark'asqa kaptin, chaymanta huk gorutina burbujapi kaqlla kichariyta atin.
Huk burbuja unaypaq hark'asqa kaptin:
- Sichus huk Pendiente Suyay
Wait
kan chayqa, kutimun. - Mana hina kaqtinqa, pachaqa qatiq kutimanmi ñawparin chaymi huk gorutinata kicharinman, sichus kanman chayqa.
- Mana chayqa, burbujaqa mana ima ruway atiqmi,
Run
mancharikun.
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 sync.Mutex
kaqpi llamk'aykuna.Mutex mana unaypaq hark'achkanchu.
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, testing/synctest
's qhawaymantalla qarquyku.
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, net.Pipe
ruwana huk paris net.Conn
s ruwan mayqinkunachus huk yuyarina ukhupi llika tinkiyta llamk'achinku chaymanta synctest pruebakunapi llamk'achiy atikunku.
Burbuja kawsay pacha
Run
ruwayqa musuq burbujapi gorutina nisqatam qallarichin. Kutimun sapa gorutina burbujapi lluqsiptin. Mancharikun sichus burbuja unaypaq hark’asqa kashan, manataqmi tiempo ñawpaqman purisqanwanqa kichariyta atikunmanchu.
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 testing/synctest
paquete llamk'achispa huk llika programata pruebapaq. Kay rikch'anapaq, net/http
paquetepa 100 Katichiy kutichiypa ruwayninta pruebasaqku.
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. testing/synctest
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 http.Transport
(huk HTTP cliente) ruwaspa mayqinchus huk yuyarina ukhupi llika tinkiyta net.Pipe
kaqwan ruwasqa llamk'achin.
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 strings.Builder
copiaspa.Rurachiq , suyayku llapa gorutinakuna burbuja kaqpi harkananpaq, chaymanta chiqaqchay manaraq imatapas kurkumanta ñawirisqaykuchu.
Sichus synctest.Wait
waqyayta qunqayku, carrera detector allinta quejakunqa huk dato carreramanta, ichaqa Wait
kaqwan kayqa mana imamanta manchachikuq.
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. synctest.Run
waqyayqa llapa lluqsinankuta suyanqa manaraq kutimuchkaspa.
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 testing/synctest
kaqmanta riqsichichkayku huk experimental paquete hina. Retroalimentación kaqmanta chaymanta experiencia kaqmanta kacharisunman utaq mana allichaywan, experimentota hinalla ruwayta utaq huk hamuq versión Go kaqmanta hurquyta.
Paqueteqa manam ñawpaqmantachu rikukun. Chayta llamk'achinaykipaq, GOEXPERIMENT=synctest
churasqawan codigoykita huñuy muyuriqniykipi.
¡Uyariyta munayku yuyayniykikunata! Sichus testing/synctest
ruwayta pruebanki , ama hina kaspa willay experienciaykikunata, allin utaq mana allin, go.dev/issue/67434 kaqpi.
Qillqasqa: Damien Neil
Fotoqa Gabriel Gusmaomanta Unsplash nisqapi
Kay qillqasqaqa kaypi tarikun