packagetoxiproxyimport("context""fmt""github.com/testcontainers/testcontainers-go/wait""github.com/testcontainers/testcontainers-go")// toxiproxyContainer represents the toxiproxy container type used in the moduletypetoxiproxyContainerstruct{testcontainers.ContainerURIstring}// startContainer creates an instance of the toxiproxy container typefuncstartContainer(ctxcontext.Context,networkstring,networkAlias[]string)(*toxiproxyContainer,error){req:=testcontainers.ContainerRequest{Image:"ghcr.io/shopify/toxiproxy:2.5.0",ExposedPorts:[]string{"8474/tcp","8666/tcp"},WaitingFor:wait.ForHTTP("/version").WithPort("8474/tcp"),Networks:[]string{network,},NetworkAliases:map[string][]string{network:networkAlias,},}container,err:=testcontainers.GenericContainer(ctx,testcontainers.GenericContainerRequest{ContainerRequest:req,Started:true,})iferr!=nil{returnnil,err}mappedPort,err:=container.MappedPort(ctx,"8474")iferr!=nil{returnnil,err}hostIP,err:=container.Host(ctx)iferr!=nil{returnnil,err}uri:=fmt.Sprintf("%s:%s",hostIP,mappedPort.Port())return&toxiproxyContainer{Container:container,URI:uri},nil}
packagetoxiproxyimport("context""fmt"toxiproxy"github.com/Shopify/toxiproxy/v2/client""github.com/go-redis/redis/v8""github.com/google/uuid""github.com/testcontainers/testcontainers-go""testing""time")funcTestToxiproxy(t*testing.T){ctx:=context.Background()newNetwork,err:=testcontainers.GenericNetwork(ctx,testcontainers.GenericNetworkRequest{ProviderType:testcontainers.ProviderDocker,NetworkRequest:testcontainers.NetworkRequest{Name:"newNetwork",CheckDuplicate:true,},})iferr!=nil{t.Fatal(err)}toxiproxyContainer,err:=startContainer(ctx,"newNetwork",[]string{"toxiproxy"})iferr!=nil{t.Fatal(err)}redisContainer,err:=setupRedis(ctx,"newNetwork",[]string{"redis"})iferr!=nil{t.Fatal(err)}// Clean up the container after the test is completet.Cleanup(func(){iferr:=toxiproxyContainer.Terminate(ctx);err!=nil{t.Fatalf("failed to terminate container: %s",err)}iferr:=redisContainer.Terminate(ctx);err!=nil{t.Fatalf("failed to terminate container: %s",err)}iferr:=newNetwork.Remove(ctx);err!=nil{t.Fatalf("failed to terminate network: %s",err)}})toxiproxyClient:=toxiproxy.NewClient(toxiproxyContainer.URI)proxy,err:=toxiproxyClient.CreateProxy("redis","0.0.0.0:8666","redis:6379")iferr!=nil{t.Fatal(err)}toxiproxyProxyPort,err:=toxiproxyContainer.MappedPort(ctx,"8666")iferr!=nil{t.Fatal(err)}toxiproxyProxyHostIP,err:=toxiproxyContainer.Host(ctx)iferr!=nil{t.Fatal(err)}redisUri:=fmt.Sprintf("redis://%s:%s?read_timeout=2s",toxiproxyProxyHostIP,toxiproxyProxyPort.Port())options,err:=redis.ParseURL(redisUri)iferr!=nil{t.Fatal(err)}redisClient:=redis.NewClient(options)deferflushRedis(ctx,*redisClient)// Set datakey:=fmt.Sprintf("{user.%s}.favoritefood",uuid.NewString())value:="Cabbage Biscuits"ttl,_:=time.ParseDuration("2h")err=redisClient.Set(ctx,key,value,ttl).Err()iferr!=nil{t.Fatal(err)}_,err=proxy.AddToxic("latency_down","latency","downstream",1.0,toxiproxy.Attributes{"latency":1000,"jitter":100,})iferr!=nil{return}// Get datasavedValue,err:=redisClient.Get(ctx,key).Result()iferr!=nil{t.Fatal(err)}// perform assertionsifsavedValue!=value{t.Fatalf("Expected value %s. Got %s.",savedValue,value)}}funcflushRedis(ctxcontext.Context,clientredis.Client)error{returnclient.FlushAll(ctx).Err()}