Skip to content

Commit 3119dc4

Browse files
authored
add integration test for pubsub. (#455)
* add integration test for pubsub. Signed-off-by: Morven Cao <lcao@redhat.com> * address comment. Signed-off-by: Morven Cao <lcao@redhat.com> * fix tekton integration test. Signed-off-by: Morven Cao <lcao@redhat.com> * fix typo. Signed-off-by: Morven Cao <lcao@redhat.com> --------- Signed-off-by: Morven Cao <lcao@redhat.com>
1 parent 0c2c7c6 commit 3119dc4

File tree

11 files changed

+530
-66
lines changed

11 files changed

+530
-66
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
secrets/db.password
4848
secrets/mqtt.password
4949
secrets/mqtt.config
50+
secrets/pubsub.config
5051
hack/mosquitto-passwd.txt
5152

5253
# Ignore image environment file

.tekton/integration-test.yaml

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ spec:
6262
TARGET_COMPONENT_NAME="maestro"
6363
REPO_URL=$(echo $SNAPSHOT | jq -r '.components[] | select(.name == "maestro").source.git.url')
6464
REPO_COMMIT=$(echo $SNAPSHOT | jq -r '.components[] | select(.name == "maestro").source.git.revision')
65-
test_output_file=${PWD}/test_output.json
65+
mqtt_test_output_file=${PWD}/mqtt_test_output.json
66+
pubsub_test_output_file=${PWD}/pubsub_test_output.json
67+
grpc_test_output_file=${PWD}/grpc_test_output.json
6668
6769
# Log Vars for Tracibility
6870
echo "REPO_URL: $REPO_URL"
@@ -84,16 +86,38 @@ spec:
8486
# Generate mqtt config file
8587
echo '{"brokerHost":"localhost:1883","username":"","password":"","topics":{"sourceEvents":"sources/maestro/consumers/+/sourceevents","agentEvents":"sources/maestro/consumers/+/agentevents"}}' > secrets/mqtt.config
8688
89+
# Generate pubsub config file
90+
echo '{"projectID":"maestro-test","endpoint":"localhost:8085","insecure":true,"topics":{"sourceEvents":"projects/maestro-test/topics/sourceevents","sourceBroadcast":"projects/maestro-test/topics/sourcebroadcast"},"subscriptions":{"agentEvents":"projects/maestro-test/subscriptions/agentevents-maestro","agentBroadcast":"projects/maestro-test/subscriptions/agentbroadcast-maestro"}}' > secrets/pubsub.config
91+
8792
# Generate db.password
8893
echo 'foobar-bizz-buzz' > secrets/db.password
8994
95+
# Wait for the pubsub emulator to be ready
96+
echo "[INFO] Waiting for pubsub emulator to be ready for connection"
97+
timeout 5m bash -c 'until curl -s http://localhost:8085 > /dev/null 2>&1; do sleep 2s; done'
98+
99+
# Initialize pubsub topics and subscriptions
100+
export PUBSUB_EMULATOR_HOST=localhost:8085
101+
export PUBSUB_PROJECT_ID=maestro-test
102+
bash hack/init-pubsub-emulator.sh
103+
90104
# Run integration tests with JSON output
91-
make test-integration integration_test_json_output="$test_output_file"
105+
make test-integration \
106+
mqtt_integration_test_json_output="$mqtt_test_output_file" \
107+
pubsub_integration_test_json_output="$pubsub_test_output_file" \
108+
grpc_integration_test_json_output="$grpc_test_output_file"
92109
93110
# Read, process, and write output in accepted format
94111
# Formatting docs: https://redhat-appstudio.github.io/book/ADR/0030-tekton-results-naming-convention.html#test_output-schema-validation
95-
FAILURES=$(cat $test_output_file | jq 'select(.Action == "fail")' | jq -r --slurp 'length')
96-
SUCCESSES=$(cat $test_output_file | jq 'select(.Action == "pass")' | jq -r --slurp 'length')
112+
# Combine results from all three broker tests
113+
MQTT_FAILURES=$(cat $mqtt_test_output_file | jq 'select(.Action == "fail")' | jq -r --slurp 'length')
114+
MQTT_SUCCESSES=$(cat $mqtt_test_output_file | jq 'select(.Action == "pass")' | jq -r --slurp 'length')
115+
PUBSUB_FAILURES=$(cat $pubsub_test_output_file | jq 'select(.Action == "fail")' | jq -r --slurp 'length')
116+
PUBSUB_SUCCESSES=$(cat $pubsub_test_output_file | jq 'select(.Action == "pass")' | jq -r --slurp 'length')
117+
GRPC_FAILURES=$(cat $grpc_test_output_file | jq 'select(.Action == "fail")' | jq -r --slurp 'length')
118+
GRPC_SUCCESSES=$(cat $grpc_test_output_file | jq 'select(.Action == "pass")' | jq -r --slurp 'length')
119+
FAILURES=$((MQTT_FAILURES + PUBSUB_FAILURES + GRPC_FAILURES))
120+
SUCCESSES=$((MQTT_SUCCESSES + PUBSUB_SUCCESSES + GRPC_SUCCESSES))
97121
# Hard-code warnings
98122
WARNINGS=0
99123
RESULT="$(if [[ $FAILURES == 0 ]]; then echo "SUCCESS"; else echo "FAILURE"; fi)"
@@ -129,6 +153,16 @@ spec:
129153
volumeMounts:
130154
- mountPath: /mosquitto/data
131155
name: mqttdata
156+
- image: gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators
157+
name: pubsub-test
158+
command:
159+
- gcloud
160+
- beta
161+
- emulators
162+
- pubsub
163+
- start
164+
- --host-port=0.0.0.0:8085
165+
- --project=maestro-test
132166
volumes:
133167
- name: pgdata
134168
emptyDir: {}

Makefile

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,25 @@ mqtt_port ?= 1883
5959
mqtt_user ?= maestro
6060
mqtt_password_file ?= ${PWD}/secrets/mqtt.password
6161
mqtt_config_file ?= ${PWD}/secrets/mqtt.config
62+
mqtt_image ?= quay.io/maestro/eclipse-mosquitto:2.0.18
63+
64+
# Pub/Sub emulator configuration
65+
pubsub_host ?= maestro-pubsub.$(namespace)
66+
pubsub_port ?= 8085
67+
pubsub_project_id ?= maestro-test
68+
pubsub_config_file ?= ${PWD}/secrets/pubsub.config
69+
pubsub_image ?= gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators
6270

6371
# Log verbosity level
6472
klog_v:=2
6573

74+
# message driver type, mqtt, grpc or pubsub, default is mqtt.
75+
MESSAGE_DRIVER_TYPE ?= mqtt
76+
6677
# Test output files
6778
unit_test_json_output ?= ${PWD}/unit-test-results.json
6879
mqtt_integration_test_json_output ?= ${PWD}/mqtt-integration-test-results.json
80+
pubsub_integration_test_json_output ?= ${PWD}/pubsub-integration-test-results.json
6981
grpc_integration_test_json_output ?= ${PWD}/grpc-integration-test-results.json
7082

7183
# Prints a list of useful targets.
@@ -77,6 +89,13 @@ help:
7789
@echo "make lint run golangci-lint"
7890
@echo "make binary compile binaries"
7991
@echo "make install compile binaries and install in GOPATH bin"
92+
@echo "make db/setup setup local PostgreSQL database"
93+
@echo "make db/teardown teardown local PostgreSQL database"
94+
@echo "make mqtt/setup setup local MQTT broker"
95+
@echo "make mqtt/teardown teardown local MQTT broker"
96+
@echo "make pubsub/setup setup local Pub/Sub emulator"
97+
@echo "make pubsub/init initialize Pub/Sub topics and subscriptions"
98+
@echo "make pubsub/teardown teardown local Pub/Sub emulator"
8099
@echo "make run run the application"
81100
@echo "make run/docs run swagger and host the api spec"
82101
@echo "make test run unit tests"
@@ -206,16 +225,21 @@ test:
206225
# make test-integration TESTFLAGS="-run TestAccounts" acts as TestAccounts* and run TestAccountsGet, TestAccountsPost, etc.
207226
# make test-integration TESTFLAGS="-run TestAccountsGet" runs TestAccountsGet
208227
# make test-integration TESTFLAGS="-short" skips long-run tests
209-
test-integration: test-integration-mqtt test-integration-grpc
228+
test-integration: test-integration-mqtt test-integration-pubsub test-integration-grpc
210229
.PHONY: test-integration
211230

212231
test-integration-mqtt:
213-
BROKER=mqtt MAESTRO_ENV=testing gotestsum --jsonfile-timing-events=$(mqtt_integration_test_json_output) --format $(TEST_SUMMARY_FORMAT) -- -p 1 -ldflags -s -v -timeout 1h $(TESTFLAGS) \
232+
MESSAGE_DRIVER_TYPE=mqtt MESSAGE_DRIVER_CONFIG=$(PWD)/secrets/mqtt.config MAESTRO_ENV=testing gotestsum --jsonfile-timing-events=$(mqtt_integration_test_json_output) --format $(TEST_SUMMARY_FORMAT) -- -count=1 -p 1 -ldflags -s -v -timeout 1h $(TESTFLAGS) \
214233
./test/integration
215234
.PHONY: test-integration-mqtt
216235

236+
test-integration-pubsub:
237+
MESSAGE_DRIVER_TYPE=pubsub MESSAGE_DRIVER_CONFIG=$(PWD)/secrets/pubsub.config PUBSUB_EMULATOR_HOST=localhost:$(pubsub_port) MAESTRO_ENV=testing gotestsum --jsonfile-timing-events=$(pubsub_integration_test_json_output) --format $(TEST_SUMMARY_FORMAT) -- -count=1 -p 1 -ldflags -s -v -timeout 1h $(TESTFLAGS) \
238+
./test/integration
239+
.PHONY: test-integration-pubsub
240+
217241
test-integration-grpc:
218-
BROKER=grpc MAESTRO_ENV=testing gotestsum --jsonfile-timing-events=$(grpc_integration_test_json_output) --format $(TEST_SUMMARY_FORMAT) -- -count=1 -p 1 -ldflags -s -v -timeout 1h $(TESTFLAGS) \
242+
MESSAGE_DRIVER_TYPE=grpc MAESTRO_ENV=testing gotestsum --jsonfile-timing-events=$(grpc_integration_test_json_output) --format $(TEST_SUMMARY_FORMAT) -- -count=1 -p 1 -ldflags -s -v -timeout 1h $(TESTFLAGS) \
219243
./test/integration
220244
.PHONY: test-integration-grpc
221245

@@ -230,7 +254,11 @@ generate:
230254

231255
run: install
232256
maestro migration
233-
maestro server
257+
@if [ "$(MESSAGE_DRIVER_TYPE)" = "grpc" ]; then \
258+
maestro server --message-broker-type=$(MESSAGE_DRIVER_TYPE); \
259+
else \
260+
maestro server --message-broker-type=$(MESSAGE_DRIVER_TYPE) --message-broker-config-file=./secrets/$(MESSAGE_DRIVER_TYPE).config; \
261+
fi
234262
.PHONY: run
235263

236264
# Run Swagger and host the api docs
@@ -325,14 +353,29 @@ mqtt/prepare:
325353
.PHONY: mqtt/setup
326354
mqtt/setup: mqtt/prepare
327355
@echo '{"brokerHost":"localhost:1883","username":"$(mqtt_user)","password":"$(shell cat $(mqtt_password_file))","topics":{"sourceEvents":"sources/maestro/consumers/+/sourceevents","agentEvents":"sources/maestro/consumers/+/agentevents"}}' > $(mqtt_config_file)
328-
$(container_tool) run --rm -v $(shell pwd)/hack:/mosquitto/data:z $(MQTT_IMAGE) mosquitto_passwd -c -b /mosquitto/data/mosquitto-passwd.txt $(mqtt_user) $(shell cat $(mqtt_password_file))
329-
$(container_tool) run --name mqtt-maestro -p 1883:1883 -v $(shell pwd)/hack/mosquitto-passwd.txt:/mosquitto/config/password.txt -v $(shell pwd)/hack/mosquitto.conf:/mosquitto/config/mosquitto.conf -d $(MQTT_IMAGE)
356+
$(container_tool) run --rm -v $(shell pwd)/hack:/mosquitto/data:z $(mqtt_image) mosquitto_passwd -c -b /mosquitto/data/mosquitto-passwd.txt $(mqtt_user) $(shell cat $(mqtt_password_file))
357+
$(container_tool) run --name mqtt-maestro -p 1883:1883 -v $(shell pwd)/hack/mosquitto-passwd.txt:/mosquitto/config/password.txt -v $(shell pwd)/hack/mosquitto.conf:/mosquitto/config/mosquitto.conf -d $(mqtt_image)
330358

331359
.PHONY: mqtt/teardown
332360
mqtt/teardown:
333361
$(container_tool) stop mqtt-maestro
334362
$(container_tool) rm mqtt-maestro
335363

364+
.PHONY: pubsub/setup
365+
pubsub/setup:
366+
@mkdir -p ${PWD}/secrets
367+
@echo '{"projectID":"$(pubsub_project_id)","endpoint":"localhost:$(pubsub_port)","insecure":true,"topics":{"sourceEvents":"projects/$(pubsub_project_id)/topics/sourceevents","sourceBroadcast":"projects/$(pubsub_project_id)/topics/sourcebroadcast"},"subscriptions":{"agentEvents":"projects/$(pubsub_project_id)/subscriptions/agentevents-maestro","agentBroadcast":"projects/$(pubsub_project_id)/subscriptions/agentbroadcast-maestro"}}' > $(pubsub_config_file)
368+
$(container_tool) run --name pubsub-maestro -p $(pubsub_port):8085 -e PUBSUB_PROJECT_ID=$(pubsub_project_id) -d $(pubsub_image) gcloud beta emulators pubsub start --host-port=0.0.0.0:8085 --project=$(pubsub_project_id)
369+
370+
.PHONY: pubsub/teardown
371+
pubsub/teardown:
372+
$(container_tool) stop pubsub-maestro
373+
$(container_tool) rm pubsub-maestro
374+
375+
.PHONY: pubsub/init
376+
pubsub/init:
377+
@PUBSUB_EMULATOR_HOST=localhost:$(pubsub_port) PUBSUB_PROJECT_ID=$(pubsub_project_id) bash hack/init-pubsub-emulator.sh
378+
336379
crc/login:
337380
@echo "Logging into CRC"
338381
@crc console --credentials -ojson | jq -r .clusterConfig.adminCredentials.password | oc login --username kubeadmin --insecure-skip-tls-verify=true https://api.crc.testing:6443

README.md

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,30 +42,40 @@ reducing the need for direct access to clusters.
4242

4343
## Run in Local Environment
4444

45-
### Make a build, run postgres and mqtt broker
45+
### Make a build, run postgres and message broker (MQTT or Pub/Sub)
4646

4747
```shell
4848

4949
# 1. build the project
5050

51-
$ go install gotest.tools/gotestsum@latest
51+
$ go install gotest.tools/gotestsum@latest
5252
$ make binary
5353

54-
# 2. run a postgres database locally in docker
54+
# 2. run a postgres database locally in docker
5555

5656
$ make db/setup
5757
$ make db/login
58-
58+
5959
root@f076ddf94520:/# psql -h localhost -U maestro maestro
6060
psql (14.4 (Debian 14.4-1.pgdg110+1))
6161
Type "help" for help.
62-
62+
6363
maestro=# \dt
6464
Did not find any relations.
6565

66-
# 3. run a mqtt broker locally in docker
66+
# 3a. run a MQTT broker locally in docker
6767

6868
$ make mqtt/setup
69+
70+
# OR
71+
72+
# 3b. run a Pub/Sub emulator locally in docker
73+
74+
$ make pubsub/setup
75+
76+
# Initialize topics and subscriptions in the emulator
77+
# Note: Requires google-cloud-pubsub Python package (pip3 install google-cloud-pubsub)
78+
$ make pubsub/init
6979
```
7080

7181
### Run database migrations
@@ -101,7 +111,12 @@ maestro=# \dt
101111
### Running the Service
102112

103113
```shell
114+
# Run with MQTT broker (default)
104115
$ make run
116+
117+
# OR run with Pub/Sub emulator
118+
# First, ensure the Pub/Sub emulator is running and configured
119+
$ MESSAGE_DRIVER_TYPE=pubsub make run
105120
```
106121

107122
#### List the consumers

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/openshift-online/maestro
33
go 1.25.0
44

55
require (
6+
cloud.google.com/go/pubsub/v2 v2.3.0
67
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0
78
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0
89
github.com/Masterminds/squirrel v1.5.4
@@ -42,6 +43,7 @@ require (
4243
go.opentelemetry.io/otel/sdk v1.39.0
4344
go.opentelemetry.io/otel/trace v1.39.0
4445
golang.org/x/oauth2 v0.32.0
46+
google.golang.org/api v0.255.0
4547
google.golang.org/grpc v1.78.0
4648
google.golang.org/protobuf v1.36.11
4749
gopkg.in/resty.v1 v1.12.0
@@ -68,7 +70,6 @@ require (
6870
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
6971
cloud.google.com/go/compute/metadata v0.9.0 // indirect
7072
cloud.google.com/go/iam v1.5.2 // indirect
71-
cloud.google.com/go/pubsub/v2 v2.3.0 // indirect
7273
filippo.io/edwards25519 v1.1.0 // indirect
7374
github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 // indirect
7475
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
@@ -184,7 +185,6 @@ require (
184185
golang.org/x/time v0.14.0 // indirect
185186
golang.org/x/tools v0.39.0 // indirect
186187
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
187-
google.golang.org/api v0.255.0 // indirect
188188
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
189189
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect
190190
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect

0 commit comments

Comments
 (0)