@@ -3,35 +3,54 @@ package billing_platform_service
33import (
44 "context"
55 "fmt"
6+ "os"
7+ "strconv"
8+ "strings"
69 "time"
710
811 "github.com/docker/docker/client"
12+ "github.com/docker/go-connections/nat"
913 "github.com/pkg/errors"
10- "github.com/smartcontractkit/chainlink-testing-framework/framework"
11- "github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose/utils"
14+ "github.com/testcontainers/testcontainers-go"
1215 "github.com/testcontainers/testcontainers-go/modules/compose"
1316 "github.com/testcontainers/testcontainers-go/wait"
17+
18+ "github.com/smartcontractkit/chainlink-testing-framework/framework"
19+ "github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose/utils"
20+ "github.com/smartcontractkit/freeport"
1421)
1522
23+ const DefaultPostgresDSN = "postgres://postgres:postgres@postgres:5432/billing_platform?sslmode=disable"
24+
1625type Output struct {
1726 BillingPlatformService * BillingPlatformServiceOutput
1827 Postgres * PostgresOutput
1928}
2029
2130type BillingPlatformServiceOutput struct {
22- GRPCInternalURL string
23- GRPCExternalURL string
31+ BillingGRPCInternalURL string
32+ BillingGRPCExternalURL string
33+ CreditGRPCInternalURL string
34+ CreditGRPCExternalURL string
2435}
2536
2637type PostgresOutput struct {
2738 DSN string
2839}
2940
3041type Input struct {
31- ComposeFile string `toml:"compose_file"`
32- ExtraDockerNetworks []string `toml:"extra_docker_networks"`
33- Output * Output `toml:"output"`
34- UseCache bool `toml:"use_cache"`
42+ ComposeFile string `toml:"compose_file"`
43+ ExtraDockerNetworks []string `toml:"extra_docker_networks"`
44+ Output * Output `toml:"output"`
45+ UseCache bool `toml:"use_cache"`
46+ ChainSelector uint64 `toml:"chain_selector"`
47+ StreamsAPIURL string `toml:"streams_api_url"`
48+ StreamsAPIKey string `toml:"streams_api_key"`
49+ StreamsAPISecret string `toml:"streams_api_secret"`
50+ RPCURL string `toml:"rpc_url"`
51+ WorkflowRegistryAddress string `toml:"workflow_registry_address"`
52+ CapabilitiesRegistryAddress string `toml:"capabilities_registry_address"`
53+ WorkflowOwners []string `toml:"workflow_owners"`
3554}
3655
3756func defaultBillingPlatformService (in * Input ) * Input {
@@ -44,8 +63,11 @@ func defaultBillingPlatformService(in *Input) *Input {
4463const (
4564 DEFAULT_STACK_NAME = "billing-platform-service"
4665
47- DEFAULT_BILLING_PLATFORM_SERVICE_GRPC_PORT = "2022"
48- DEFAULT_BILLING_PLATFORM_SERVICE_SERVICE_NAME = "billing-platform-service"
66+ DEFAULT_BILLING_PLATFORM_SERVICE_BILLING_GRPC_PORT = "2222"
67+ DEFAULT_BILLING_PLATFORM_SERVICE_CREDIT_GRPC_PORT = "2223"
68+ DEFAULT_POSTGRES_PORT = "5432"
69+ DEFAULT_BILLING_PLATFORM_SERVICE_SERVICE_NAME = "billing-platform-service"
70+ DEFAULT_POSTGRES_SERVICE_NAME = "postgres"
4971)
5072
5173func New (in * Input ) (* Output , error ) {
@@ -79,7 +101,48 @@ func New(in *Input) (*Output, error) {
79101 ctx , cancel := context .WithTimeout (context .Background (), 2 * time .Minute )
80102 defer cancel ()
81103
82- upErr := stack .Up (ctx )
104+ // Start the stackwith all environment variables from the host process
105+ // set development defaults for necessary environment variables and allow them to be overridden by the host process
106+ envVars := make (map [string ]string )
107+
108+ envVars ["MAINNET_WORKFLOW_REGISTRY_CHAIN_SELECTOR" ] = strconv .FormatUint (in .ChainSelector , 10 )
109+ envVars ["MAINNET_WORKFLOW_REGISTRY_CONTRACT_ADDRESS" ] = in .WorkflowRegistryAddress
110+ envVars ["MAINNET_WORKFLOW_REGISTRY_RPC_URL" ] = in .RPCURL
111+ envVars ["MAINNET_WORKFLOW_REGISTRY_FINALITY_DEPTH" ] = "0" // Instant finality on devnet
112+ envVars ["KMS_PROOF_SIGNING_KEY_ID" ] = "00000000-0000-0000-0000-000000000001" // provisioned via LocalStack
113+ envVars ["VERIFIER_INITIAL_INTERVAL" ] = "0s" // reduced to force verifier to start immediately in integration tests
114+ envVars ["VERIFIER_MAXIMUM_INTERVAL" ] = "1s" // reduced to force verifier to start immediately in integration tests
115+ envVars ["LINKING_REQUEST_COOLDOWN" ] = "0s" // reduced to force consequtive linking requests to be processed immediately in integration tests
116+
117+ envVars ["MAINNET_CAPABILITIES_REGISTRY_CHAIN_SELECTOR" ] = strconv .FormatUint (in .ChainSelector , 10 )
118+ envVars ["MAINNET_CAPABILITIES_REGISTRY_CONTRACT_ADDRESS" ] = in .CapabilitiesRegistryAddress
119+ envVars ["MAINNET_CAPABILITIES_REGISTRY_RPC_URL" ] = in .RPCURL
120+ envVars ["MAINNET_CAPABILITIES_REGISTRY_FINALITY_DEPTH" ] = "10" // Arbitrary value, adjust as needed
121+
122+ envVars ["TEST_OWNERS" ] = strings .Join (in .WorkflowOwners , "," )
123+ envVars ["STREAMS_API_URL" ] = in .StreamsAPIURL
124+ envVars ["STREAMS_API_KEY" ] = in .StreamsAPIKey
125+ envVars ["STREAMS_API_SECRET" ] = in .StreamsAPISecret
126+
127+ for _ , env := range os .Environ () {
128+ pair := strings .SplitN (env , "=" , 2 )
129+ if len (pair ) == 2 {
130+ envVars [pair [0 ]] = pair [1 ]
131+ }
132+ }
133+
134+ // set these env vars after reading env vars from host
135+ port , err := freeport .Take (1 )
136+ if err != nil {
137+ return nil , errors .Wrap (err , "failed to get free port for Billing Platform Service postgres" )
138+ }
139+
140+ envVars ["POSTGRES_PORT" ] = strconv .FormatInt (int64 (port [0 ]), 10 )
141+ envVars ["DEFAULT_DSN" ] = DefaultPostgresDSN
142+
143+ upErr := stack .
144+ WithEnv (envVars ).
145+ Up (ctx )
83146
84147 if upErr != nil {
85148 return nil , errors .Wrap (upErr , "failed to start stack for Billing Platform Service" )
@@ -88,7 +151,8 @@ func New(in *Input) (*Output, error) {
88151 stack .WaitForService (DEFAULT_BILLING_PLATFORM_SERVICE_SERVICE_NAME ,
89152 wait .ForAll (
90153 wait .ForLog ("GRPC server is live" ).WithPollInterval (200 * time .Millisecond ),
91- wait .ForListeningPort (DEFAULT_BILLING_PLATFORM_SERVICE_GRPC_PORT ),
154+ wait .ForListeningPort (DEFAULT_BILLING_PLATFORM_SERVICE_BILLING_GRPC_PORT ),
155+ wait .ForListeningPort (DEFAULT_BILLING_PLATFORM_SERVICE_CREDIT_GRPC_PORT ),
92156 ).WithDeadline (1 * time .Minute ),
93157 )
94158
@@ -97,6 +161,11 @@ func New(in *Input) (*Output, error) {
97161 return nil , errors .Wrap (billingErr , "failed to get billing-platform-service container" )
98162 }
99163
164+ postgresContainer , postgresErr := stack .ServiceContainer (ctx , DEFAULT_POSTGRES_SERVICE_NAME )
165+ if postgresErr != nil {
166+ return nil , errors .Wrap (postgresErr , "failed to get postgres container" )
167+ }
168+
100169 cli , cliErr := client .NewClientWithOpts (
101170 client .FromEnv ,
102171 client .WithAPIVersionNegotiation (),
@@ -139,23 +208,61 @@ func New(in *Input) (*Output, error) {
139208 return nil , errors .Wrap (billingExternalHostErr , "failed to get host for Billing Platform Service" )
140209 }
141210
142- // get mapped port for billing platform service
143- billingExternalPort , billingExternalPortErr := utils .FindMappedPort (ctx , 20 * time .Second , billingContainer , DEFAULT_BILLING_PLATFORM_SERVICE_GRPC_PORT )
144- if billingExternalPortErr != nil {
145- return nil , errors .Wrap (billingExternalPortErr , "failed to get mapped port for Chip Ingress" )
211+ // get hosts for billing platform service
212+ postgresExternalHost , postgresExternalHostErr := utils .GetContainerHost (ctx , postgresContainer )
213+ if postgresExternalHostErr != nil {
214+ return nil , errors .Wrap (postgresExternalHostErr , "failed to get host for postgres" )
215+ }
216+
217+ // get mapped ports for billing platform service
218+ serviceOutput , err := getExternalPorts (ctx , billingExternalHost , billingContainer )
219+ if err != nil {
220+ return nil , errors .Wrap (err , "failed to get mapped port for Billing Platform Service" )
221+ }
222+
223+ externalPostgresPort , err := utils .FindMappedPort (ctx , 20 * time .Second , postgresContainer , nat .Port (DEFAULT_POSTGRES_PORT + "/tcp" ))
224+ if err != nil {
225+ return nil , errors .Wrap (err , "failed to get mapped port for postgres" )
146226 }
147227
148228 output := & Output {
149- BillingPlatformService : & BillingPlatformServiceOutput {
150- GRPCInternalURL : fmt .Sprintf ("http://%s:%s" , DEFAULT_BILLING_PLATFORM_SERVICE_SERVICE_NAME , DEFAULT_BILLING_PLATFORM_SERVICE_GRPC_PORT ),
151- GRPCExternalURL : fmt .Sprintf ("http://%s:%s" , billingExternalHost , billingExternalPort .Port ()),
152- },
229+ BillingPlatformService : serviceOutput ,
153230 Postgres : & PostgresOutput {
154-
155- }
231+ DSN : fmt . Sprintf ( "postgres://postgres:postgres@%s:%s/billing_platform" , postgresExternalHost , externalPostgresPort . Port ()),
232+ },
156233 }
157234
158235 framework .L .Info ().Msg ("Billing Platform Service stack start" )
159236
160237 return output , nil
161238}
239+
240+ func getExternalPorts (ctx context.Context , billingExternalHost string , billingContainer * testcontainers.DockerContainer ) (* BillingPlatformServiceOutput , error ) {
241+ ports := map [string ]nat.Port {
242+ "billing" : DEFAULT_BILLING_PLATFORM_SERVICE_BILLING_GRPC_PORT ,
243+ "credit" : DEFAULT_BILLING_PLATFORM_SERVICE_CREDIT_GRPC_PORT ,
244+ }
245+
246+ output := BillingPlatformServiceOutput {}
247+
248+ for name , defaultPort := range ports {
249+ externalPort , err := utils .FindMappedPort (ctx , 20 * time .Second , billingContainer , defaultPort )
250+ if err != nil {
251+ return nil , errors .Wrap (err , "failed to get mapped port for Billing Platform Service" )
252+ }
253+
254+ internal := fmt .Sprintf ("http://%s:%s" , DEFAULT_BILLING_PLATFORM_SERVICE_SERVICE_NAME , defaultPort )
255+ external := fmt .Sprintf ("http://%s:%s" , billingExternalHost , externalPort .Port ())
256+
257+ switch name {
258+ case "billing" :
259+ output .BillingGRPCInternalURL = internal
260+ output .BillingGRPCExternalURL = external
261+ case "credit" :
262+ output .CreditGRPCInternalURL = internal
263+ output .CreditGRPCExternalURL = external
264+ }
265+ }
266+
267+ return & output , nil
268+ }
0 commit comments