github.com/rudderlabs/rudder-go-kit@v0.30.0/testhelper/docker/resource/transformer/transformer.go (about) 1 package transformer 2 3 import ( 4 "errors" 5 "fmt" 6 "net/http" 7 "strings" 8 9 "github.com/samber/lo" 10 11 dockertesthelper "github.com/rudderlabs/rudder-go-kit/testhelper/docker" 12 13 "github.com/ory/dockertest/v3" 14 "github.com/ory/dockertest/v3/docker" 15 16 "github.com/rudderlabs/rudder-go-kit/httputil" 17 "github.com/rudderlabs/rudder-go-kit/testhelper/docker/resource" 18 ) 19 20 type Resource struct { 21 TransformerURL string 22 Port string 23 } 24 25 type config struct { 26 repository string 27 tag string 28 exposedPorts []string 29 envs []string 30 extraHosts []string 31 } 32 33 func (c *config) setBackendConfigURL(url string) { 34 c.envs = append( 35 lo.Filter(c.envs, func(s string, _ int) bool { 36 return !strings.HasPrefix(s, "CONFIG_BACKEND_URL=") 37 }), 38 "CONFIG_BACKEND_URL="+url) 39 } 40 41 // WithUserTransformations will mock BE config to set transformation for given transformation versionID to transformation function map 42 // 43 // - events with transformationVersionID not present in map will not be transformed and transformer will return 404 for those requests 44 // 45 // - WithUserTransformations should not be used with WithConfigBackendURL option 46 // 47 // - only javascript transformation functions are supported 48 // 49 // e.g. 50 // 51 // WithUserTransformations(map[string]string{ 52 // "transform-version-id-1": `export function transformEvent(event, metadata) { 53 // event.transformed=true 54 // return event; 55 // }`, 56 // }) 57 func WithUserTransformations(transformations map[string]string, cleaner resource.Cleaner) func(*config) { 58 return func(conf *config) { 59 backendConfigSvc := newTestBackendConfigServer(transformations) 60 61 conf.setBackendConfigURL(dockertesthelper.ToInternalDockerHost(backendConfigSvc.URL)) 62 conf.extraHosts = append(conf.extraHosts, "host.docker.internal:host-gateway") 63 cleaner.Cleanup(func() { 64 backendConfigSvc.Close() 65 }) 66 } 67 } 68 69 // WithConnectionToHostEnabled lets transformer container connect with the host machine 70 // i.e. transformer container will be able to access localhost of the host machine 71 func WithConnectionToHostEnabled() func(*config) { 72 return func(conf *config) { 73 conf.extraHosts = append(conf.extraHosts, "host.docker.internal:host-gateway") 74 } 75 } 76 77 // WithConfigBackendURL lets transformer use custom backend config server for transformations 78 // WithConfigBackendURL should not be used with WithUserTransformations option 79 func WithConfigBackendURL(url string) func(*config) { 80 return func(conf *config) { 81 conf.setBackendConfigURL(dockertesthelper.ToInternalDockerHost(url)) 82 } 83 } 84 85 func WithDockerImageTag(tag string) func(*config) { 86 return func(conf *config) { 87 conf.tag = tag 88 } 89 } 90 91 func Setup(pool *dockertest.Pool, d resource.Cleaner, opts ...func(conf *config)) (*Resource, error) { 92 // Set Rudder Transformer 93 // pulls an image first to make sure we don't have an old cached version locally, 94 // then it creates a container based on it and runs it 95 conf := &config{ 96 repository: "rudderstack/rudder-transformer", 97 tag: "latest", 98 exposedPorts: []string{"9090"}, 99 envs: []string{ 100 "CONFIG_BACKEND_URL=https://api.rudderstack.com", 101 }, 102 } 103 104 for _, opt := range opts { 105 opt(conf) 106 } 107 108 err := pool.Client.PullImage(docker.PullImageOptions{ 109 Repository: conf.repository, 110 Tag: conf.tag, 111 }, docker.AuthConfiguration{}) 112 if err != nil { 113 return nil, fmt.Errorf("failed to pull image: %w", err) 114 } 115 transformerContainer, err := pool.RunWithOptions(&dockertest.RunOptions{ 116 Repository: conf.repository, 117 Tag: conf.tag, 118 ExposedPorts: conf.exposedPorts, 119 Env: conf.envs, 120 ExtraHosts: conf.extraHosts, 121 }) 122 if err != nil { 123 return nil, err 124 } 125 126 d.Cleanup(func() { 127 if err := pool.Purge(transformerContainer); err != nil { 128 d.Log("Could not purge resource:", err) 129 } 130 }) 131 132 transformerResource := &Resource{ 133 TransformerURL: fmt.Sprintf("http://localhost:%s", transformerContainer.GetPort("9090/tcp")), 134 Port: transformerContainer.GetPort("9090/tcp"), 135 } 136 137 err = pool.Retry(func() (err error) { 138 resp, err := http.Get(transformerResource.TransformerURL + "/health") 139 if err != nil { 140 return err 141 } 142 defer func() { httputil.CloseResponse(resp) }() 143 if resp.StatusCode != http.StatusOK { 144 return errors.New(resp.Status) 145 } 146 return nil 147 }) 148 if err != nil { 149 return nil, err 150 } 151 152 return transformerResource, nil 153 }