Skip to content

Commit 7c17584

Browse files
author
nareshmmr
committed
base 2 commit
1 parent 5d947b0 commit 7c17584

File tree

19 files changed

+466
-135
lines changed

19 files changed

+466
-135
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,6 @@ __debug*
7373
.private_chains/*
7474

7575
.direnv
76+
77+
# asdf
78+
.tool-versions
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
package job_distributor
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
"time"
7+
8+
"github.com/google/uuid"
9+
"github.com/pkg/errors"
10+
"github.com/rs/zerolog"
11+
"github.com/rs/zerolog/log"
12+
tc "github.com/testcontainers/testcontainers-go"
13+
tcwait "github.com/testcontainers/testcontainers-go/wait"
14+
15+
"github.com/goplugin/plugin-testing-framework/lib/docker"
16+
"github.com/goplugin/plugin-testing-framework/lib/docker/test_env"
17+
"github.com/goplugin/plugin-testing-framework/lib/logging"
18+
"github.com/goplugin/plugin-testing-framework/lib/utils/testcontext"
19+
)
20+
21+
const (
22+
JDContainerName string = "job-distributor"
23+
DEAFULTJDContainerPort string = "42242"
24+
DEFAULTCSAKeyEncryptionKey string = "!PASsword000!"
25+
DEAFULTWSRPCContainerPort string = "8080"
26+
)
27+
28+
type Option = func(j *Component)
29+
30+
type Component struct {
31+
test_env.EnvComponent
32+
Grpc string
33+
Wsrpc string
34+
InternalGRPC string
35+
InternalWSRPC string
36+
l zerolog.Logger
37+
t *testing.T
38+
dbConnection string
39+
containerPort string
40+
wsrpcPort string
41+
csaKeyEncryptionKey string
42+
}
43+
44+
func (j *Component) startOrRestartContainer(withReuse bool) error {
45+
req := j.getContainerRequest()
46+
l := logging.GetTestContainersGoTestLogger(j.t)
47+
c, err := docker.StartContainerWithRetry(j.l, tc.GenericContainerRequest{
48+
ContainerRequest: *req,
49+
Started: true,
50+
Reuse: withReuse,
51+
Logger: l,
52+
})
53+
if err != nil {
54+
return err
55+
}
56+
j.Container = c
57+
ctx := testcontext.Get(j.t)
58+
host, err := test_env.GetHost(ctx, c)
59+
if err != nil {
60+
return errors.Wrapf(err, "cannot get host for container %s", j.ContainerName)
61+
}
62+
63+
p, err := c.MappedPort(ctx, test_env.NatPort(j.containerPort))
64+
if err != nil {
65+
return errors.Wrapf(err, "cannot get container mapped port for container %s", j.ContainerName)
66+
}
67+
j.Grpc = fmt.Sprintf("%s:%s", host, p.Port())
68+
69+
p, err = c.MappedPort(ctx, test_env.NatPort(j.wsrpcPort))
70+
if err != nil {
71+
return errors.Wrapf(err, "cannot get wsrpc mapped port for container %s", j.ContainerName)
72+
}
73+
j.Wsrpc = fmt.Sprintf("%s:%s", host, p.Port())
74+
j.InternalGRPC = fmt.Sprintf("%s:%s", j.ContainerName, j.containerPort)
75+
76+
j.InternalWSRPC = fmt.Sprintf("%s:%s", j.ContainerName, j.wsrpcPort)
77+
j.l.Info().
78+
Str("containerName", j.ContainerName).
79+
Str("grpcURI", j.Grpc).
80+
Str("wsrpcURI", j.Wsrpc).
81+
Str("internalGRPC", j.InternalGRPC).
82+
Str("internalWSRPC", j.InternalWSRPC).
83+
Msg("Started Job Distributor container")
84+
85+
return nil
86+
}
87+
88+
func (j *Component) getContainerRequest() *tc.ContainerRequest {
89+
return &tc.ContainerRequest{
90+
Name: j.ContainerName,
91+
Image: fmt.Sprintf("%s:%s", j.ContainerImage, j.ContainerVersion),
92+
ExposedPorts: []string{
93+
test_env.NatPortFormat(j.containerPort),
94+
test_env.NatPortFormat(j.wsrpcPort),
95+
},
96+
Env: map[string]string{
97+
"DATABASE_URL": j.dbConnection,
98+
"PORT": j.containerPort,
99+
"NODE_RPC_PORT": j.wsrpcPort,
100+
"CSA_KEY_ENCRYPTION_SECRET": j.csaKeyEncryptionKey,
101+
},
102+
Networks: j.Networks,
103+
WaitingFor: tcwait.ForAll(
104+
tcwait.ForListeningPort(test_env.NatPort(j.containerPort)),
105+
tcwait.ForListeningPort(test_env.NatPort(j.wsrpcPort)),
106+
),
107+
LifecycleHooks: []tc.ContainerLifecycleHooks{
108+
{
109+
PostStarts: j.PostStartsHooks,
110+
PostStops: j.PostStopsHooks,
111+
},
112+
},
113+
}
114+
}
115+
116+
func (j *Component) StartContainer() error {
117+
return j.startOrRestartContainer(false)
118+
}
119+
120+
func (j *Component) RestartContainer() error {
121+
return j.startOrRestartContainer(true)
122+
}
123+
124+
func New(networks []string, opts ...Option) *Component {
125+
id, _ := uuid.NewRandom()
126+
j := &Component{
127+
EnvComponent: test_env.EnvComponent{
128+
ContainerName: fmt.Sprintf("%s-%s", JDContainerName, id.String()[0:8]),
129+
Networks: networks,
130+
StartupTimeout: 2 * time.Minute,
131+
},
132+
containerPort: DEAFULTJDContainerPort,
133+
wsrpcPort: DEAFULTWSRPCContainerPort,
134+
csaKeyEncryptionKey: DEFAULTCSAKeyEncryptionKey,
135+
l: log.Logger,
136+
}
137+
j.SetDefaultHooks()
138+
for _, opt := range opts {
139+
opt(j)
140+
}
141+
return j
142+
}
143+
144+
func WithTestInstance(t *testing.T) Option {
145+
return func(j *Component) {
146+
j.l = logging.GetTestLogger(t)
147+
j.t = t
148+
}
149+
}
150+
151+
func WithContainerPort(port string) Option {
152+
return func(j *Component) {
153+
j.containerPort = port
154+
}
155+
}
156+
157+
func WithWSRPCContainerPort(port string) Option {
158+
return func(j *Component) {
159+
j.wsrpcPort = port
160+
}
161+
}
162+
163+
func WithDBURL(db string) Option {
164+
return func(j *Component) {
165+
if db != "" {
166+
j.dbConnection = db
167+
}
168+
}
169+
}
170+
171+
func WithContainerName(name string) Option {
172+
return func(j *Component) {
173+
j.ContainerName = name
174+
}
175+
}
176+
177+
func WithImage(image string) Option {
178+
return func(j *Component) {
179+
j.ContainerImage = image
180+
}
181+
}
182+
183+
func WithVersion(version string) Option {
184+
return func(j *Component) {
185+
j.ContainerVersion = version
186+
}
187+
}
188+
189+
func WithCSAKeyEncryptionKey(key string) Option {
190+
return func(j *Component) {
191+
j.csaKeyEncryptionKey = key
192+
}
193+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package job_distributor
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
"google.golang.org/grpc"
9+
"google.golang.org/grpc/credentials/insecure"
10+
11+
"github.com/goplugin/plugin-testing-framework/lib/docker"
12+
"github.com/goplugin/plugin-testing-framework/lib/docker/test_env"
13+
"github.com/goplugin/plugin-testing-framework/lib/logging"
14+
)
15+
16+
func TestJDSpinUp(t *testing.T) {
17+
t.Skipf("TODO enable this when jd image is available in ci")
18+
l := logging.GetTestLogger(t)
19+
network, err := docker.CreateNetwork(l)
20+
require.NoError(t, err)
21+
22+
// create a postgres first
23+
pg, err := test_env.NewPostgresDb(
24+
[]string{network.Name},
25+
test_env.WithPostgresDbName("jd-db"),
26+
test_env.WithPostgresImageVersion("14.1"))
27+
require.NoError(t, err)
28+
err = pg.StartContainer()
29+
require.NoError(t, err)
30+
31+
jd := New([]string{network.Name},
32+
//TODO: replace with actual image
33+
WithImage("localhost:5001/jd"),
34+
WithVersion("latest"),
35+
WithDBURL(pg.InternalURL.String()),
36+
)
37+
38+
err = jd.StartContainer()
39+
require.NoError(t, err)
40+
// create a jd connection
41+
_, err = newConnection(jd.Grpc)
42+
require.NoError(t, err)
43+
}
44+
45+
func newConnection(target string) (*grpc.ClientConn, error) {
46+
var opts []grpc.DialOption
47+
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
48+
conn, err := grpc.NewClient(target, opts...)
49+
if err != nil {
50+
return nil, fmt.Errorf("Failed to connect to service at %s. Err: %w", target, err)
51+
}
52+
53+
return conn, nil
54+
}

lib/docker/test_env/postgres.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,13 @@ func (pg *PostgresDb) startOrRestartContainer(withReuse bool) error {
158158
internalUrl, err := url.Parse(fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=disable",
159159
pg.User, pg.Password, pg.ContainerName, "5432", pg.DbName))
160160
if err != nil {
161-
return fmt.Errorf("error parsing mercury db internal url: %w", err)
161+
return errors.Wrap(err, "error parsing db internal url")
162162
}
163163
pg.InternalURL = internalUrl
164164
externalUrl, err := url.Parse(fmt.Sprintf("postgres://%s:%[email protected]:%s/%s?sslmode=disable",
165165
pg.User, pg.Password, externalPort.Port(), pg.DbName))
166166
if err != nil {
167-
return fmt.Errorf("error parsing mercury db external url: %w", err)
167+
return errors.Wrap(err, "error parsing db external url")
168168
}
169169
pg.ExternalURL = externalUrl
170170

lib/docker/test_env/utils.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,21 @@ func GetHost(ctx context.Context, container tc.Container) (string, error) {
3131
return host, nil
3232
}
3333

34+
// GetEndpointFromPort returns the endpoint of a container associated with a port,
35+
// if localhost then force ipv4 localhost
36+
// to avoid ipv6 docker bugs https://github.com/moby/moby/issues/42442 https://github.com/moby/moby/issues/42375
37+
func GetEndpointFromPort(ctx context.Context, container tc.Container, endpointType string, portStr string) (string, error) {
38+
port, err := nat.NewPort("tcp", portStr)
39+
if err != nil {
40+
return "", err
41+
}
42+
endpoint, err := container.PortEndpoint(ctx, port, endpointType)
43+
if err != nil {
44+
return "", err
45+
}
46+
return strings.Replace(endpoint, "localhost", "127.0.0.1", 1), nil
47+
}
48+
3449
// GetEndpoint returns the endpoint of a container, if localhost then force ipv4 localhost
3550
// to avoid ipv6 docker bugs https://github.com/moby/moby/issues/42442 https://github.com/moby/moby/issues/42375
3651
func GetEndpoint(ctx context.Context, container tc.Container, endpointType string) (string, error) {

lib/go.mod

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ require (
4242
github.com/testcontainers/testcontainers-go v0.28.0
4343
go.uber.org/atomic v1.11.0
4444
go.uber.org/zap v1.26.0
45-
golang.org/x/net v0.26.0
45+
golang.org/x/net v0.29.0
4646
golang.org/x/oauth2 v0.21.0
47-
golang.org/x/sync v0.7.0
48-
golang.org/x/text v0.16.0
47+
golang.org/x/sync v0.8.0
48+
golang.org/x/text v0.18.0
4949
k8s.io/api v0.31.0
5050
k8s.io/apimachinery v0.31.0
5151
k8s.io/cli-runtime v0.31.0
@@ -298,17 +298,17 @@ require (
298298
go.uber.org/ratelimit v0.3.0 // indirect
299299
go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect
300300
golang.org/x/arch v0.4.0 // indirect
301-
golang.org/x/crypto v0.25.0 // indirect
301+
golang.org/x/crypto v0.27.0 // indirect
302302
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
303303
golang.org/x/mod v0.19.0 // indirect
304-
golang.org/x/sys v0.22.0 // indirect
305-
golang.org/x/term v0.22.0 // indirect
304+
golang.org/x/sys v0.25.0 // indirect
305+
golang.org/x/term v0.24.0 // indirect
306306
golang.org/x/time v0.6.0 // indirect
307307
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
308308
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
309309
google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect
310310
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
311-
google.golang.org/grpc v1.65.0 // indirect
311+
google.golang.org/grpc v1.65.0
312312
google.golang.org/protobuf v1.34.2 // indirect
313313
gopkg.in/inf.v0 v0.9.1 // indirect
314314
gopkg.in/yaml.v2 v2.4.0 // indirect
@@ -327,3 +327,5 @@ require (
327327
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
328328
sigs.k8s.io/yaml v1.4.0 // indirect
329329
)
330+
331+
retract v1.50.0

0 commit comments

Comments
 (0)