Skip to content

test(mongodb): add live integration tests for the MongoDB proxy#104

Open
bharathnr1 wants to merge 2 commits into
nudgebee:mainfrom
bharathnr1:test/mongodb-proxy-integration
Open

test(mongodb): add live integration tests for the MongoDB proxy#104
bharathnr1 wants to merge 2 commits into
nudgebee:mainfrom
bharathnr1:test/mongodb-proxy-integration

Conversation

@bharathnr1

Copy link
Copy Markdown

Description

pkg/proxy/mongodb/proxy_test.go covers URI building and the not-configured paths, but the handlers that actually run commands — serverStatus / replSetGetStatus / currentOp / find / aggregate — are never exercised against a live MongoDB (the unit test even notes "skip since it requires real mongo").

This adds build-tagged (//go:build integration) integration tests for the read-only diagnostics. Given a reachable MongoDB via FORAGER_MONGO_TEST_HOST, they configure the proxy and assert each diagnostic returns a 200 with the expected document shape:

  • mongo_server_statusok / connections / uptime
  • mongo_current_opsinprog
  • mongo_repl_statusset / members (when FORAGER_MONGO_TEST_REPLICA_SET is set; otherwise asserts the handler surfaces the error rather than panicking)

They skip cleanly when no database is configured, so go test ./... (and make test) are unaffected — this is opt-in and adds no dependencies.

How Has This Been Tested?

docker run -d -p 27017:27017 mongo:7 --replSet rs0 --bind_ip_all
docker exec <id> mongosh --quiet --eval "rs.initiate({_id:'rs0',members:[{_id:0,host:'localhost:27017'}]})"
FORAGER_MONGO_TEST_HOST=localhost FORAGER_MONGO_TEST_REPLICA_SET=rs0 \
  go test -tags integration -run TestIntegration -v ./pkg/proxy/mongodb/
--- PASS: TestIntegration_ServerStatus (0.01s)
--- PASS: TestIntegration_CurrentOps (0.01s)
--- PASS: TestIntegration_ReplStatus (0.00s)
ok  	nudgebee/forager/pkg/proxy/mongodb

Verified against MongoDB 7.0 (single-node replica set). Without FORAGER_MONGO_TEST_HOST, the tests skip.

Context

Came up while validating the MongoDB AI-troubleshooting tool in nudgebee/nudgebee#385, which relies on these forager diagnostics — this gives that path reproducible coverage on the forager side.

🤖 Generated with Claude Code

The existing proxy_test.go only covers URI building and the not-configured
paths; the handlers that run real commands (serverStatus / replSetGetStatus /
currentOp / find / aggregate) are never exercised against a live MongoDB.

Add build-tagged (`//go:build integration`) integration tests that, given a
reachable MongoDB via FORAGER_MONGO_TEST_HOST, configure the proxy and assert
the read-only diagnostics return a 200 with the expected document shape. They
skip cleanly when no database is configured, so `go test ./...` is unaffected.

Run:
  docker run -d -p 27017:27017 mongo:7 --replSet rs0 --bind_ip_all
  docker exec <id> mongosh --quiet --eval "rs.initiate({_id:'rs0',members:[{_id:0,host:'localhost:27017'}]})"
  FORAGER_MONGO_TEST_HOST=localhost FORAGER_MONGO_TEST_REPLICA_SET=rs0 \
    go test -tags integration -run TestIntegration -v ./pkg/proxy/mongodb/

Signed-off-by: Bharath Nallapeta <bnallapeta@mirantis.com>
@cla-assistant

cla-assistant Bot commented Jun 26, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces integration tests for the MongoDB proxy in proxy_integration_test.go, which run against a live MongoDB instance. The feedback suggests adding a defensive nil check for the response object in the decodeData helper function to prevent potential nil pointer dereference panics during test execution.

Comment on lines +65 to +72
func decodeData(t *testing.T, resp *proxy.ActionResponse, err error, action string) map[string]any {
t.Helper()
if err != nil {
t.Fatalf("%s: unexpected error: %v", action, err)
}
if resp.StatusCode != 200 {
t.Fatalf("%s: expected status 200, got %d (data=%s)", action, resp.StatusCode, resp.Data)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If err is nil but resp is also nil (for example, if a handler incorrectly returns nil, nil), accessing resp.StatusCode will cause a panic. Adding a defensive check to ensure resp is not nil before accessing its fields will allow the test to fail gracefully with a clear message.

func decodeData(t *testing.T, resp *proxy.ActionResponse, err error, action string) map[string]any {
	t.Helper()
	if err != nil {
		t.Fatalf("%s: unexpected error: %v", action, err)
	}
	if resp == nil {
		t.Fatalf("%s: response is nil", action)
	}
	if resp.StatusCode != 200 {
		t.Fatalf("%s: expected status 200, got %d (data=%s)", action, resp.StatusCode, resp.Data)
	}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call — added the resp == nil guard in decodeData before dereferencing, so a handler returning (nil, nil) fails with a clear message instead of panicking. Pushed in 280a392; gofmt/go vet -tags integration clean.

Addresses review: guard against a handler returning (nil, nil) so the test
fails with a clear message instead of panicking on resp.StatusCode.

Signed-off-by: Bharath Nallapeta <bnallapeta@mirantis.com>
@bharathnr1

Copy link
Copy Markdown
Author

Have signed the CLA twice. But its not recognizing it.

@mayankpande88 @blue4209211

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants