Skip to content

EPMRPP-110724 || MCP Server. GA Analytics. Add RP instanceId parameter#77

Merged
AleksandrParamonoff merged 1 commit intodevelopfrom
add-new-metric-parameter
Jan 15, 2026
Merged

EPMRPP-110724 || MCP Server. GA Analytics. Add RP instanceId parameter#77
AleksandrParamonoff merged 1 commit intodevelopfrom
add-new-metric-parameter

Conversation

@AleksandrParamonoff
Copy link
Contributor

No description provided.

@coderabbitai
Copy link

coderabbitai bot commented Jan 14, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Summary by CodeRabbit

  • New Features

    • Analytics now includes ReportPortal instance IDs in event reports and lazily retrieves and caches the ID.
    • Network fetches use a timeout and improved retry/logging behavior.
  • Bug Fixes

    • Analytics initialization validates host URL to prevent invalid setup.
  • Tests

    • Added tests for instance ID retrieval, lazy-loading, retry behavior, and empty-host handling.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Adds lazy, retried fetching of ReportPortal instance ID into Analytics: NewAnalytics now accepts an rpHostURL; Analytics stores rpHostURL, lazily obtains instanceID from /api/info (5s timeout) with atomic fast-path and mutex slow-path, and includes instanceID in event Params when available.

Changes

Cohort / File(s) Summary
Core Analytics Instance ID Logic
internal/reportportal/analytics.go
Added instanceID storage and guards (atomic.Bool, sync.Mutex), rpHostURL field, instanceIDFetchTimeout (5s); implemented ensureInstanceID() (fast/slow path) and fetchInstanceID(hostURL, httpClient) (GET /api/info, JSON parsing); updated NewAnalytics(...) signature to accept rpHostURL; sendBatchMetrics calls ensureInstanceID() and conditionally includes instanceID in event Params; new 10s HTTP client used.
Tests: instance ID behavior
internal/reportportal/analytics_test.go
Updated all NewAnalytics test calls to supply hostURL (often ""); added TestAnalyticsInstanceIDFetching with subtests for lazy loading, retry behavior, and empty-host handling; added encoding/json and httptest usage.
Call site updates
internal/reportportal/http_server.go, internal/reportportal/server.go
Updated NewAnalytics(...) invocations to pass config.HostURL.String() or host string as the new fourth argument; NewHTTPServer now validates HostURL non-nil.
Manifest
go.mod
Minor adjustments in module file to match imports/timeouts introduced.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Analytics
    participant RP_API
    participant GA4_API

    Client->>Analytics: sendBatchMetrics()
    Analytics->>Analytics: ensureInstanceID()
    alt instanceID not fetched
        Analytics->>RP_API: GET /api/info (5s timeout)
        alt success
            RP_API-->>Analytics: JSON with extensions.result["server.details.instance"]
            Analytics->>Analytics: parse & store instanceID (atomic set)
        else fail/timeout
            RP_API-->>Analytics: error/timeout
            Analytics->>Analytics: log, leave unset (retry later)
        end
    end
    Analytics->>GA4_API: POST batch (events include instanceID when present)
    GA4_API-->>Analytics: response
    Analytics-->>Client: return result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • AmsterGet
  • avarabyeu

Poem

A tiny ID behind the gate,
Analytics waits, it will not wait.
With mutex calm and timeout wise,
It fetches truth from RP skies.

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning No pull request description was provided by the author, making it impossible to assess whether it relates to the changeset. Add a detailed description explaining the purpose of the instanceId parameter, its usage in GA events, and any relevant context about the lazy-fetch implementation.
Docstring Coverage ⚠️ Warning Docstring coverage is 21.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the JIRA issue (EPMRPP-110724) and accurately describes the main change: adding RP instanceId parameter to GA analytics.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings


📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c17eca1 and 76323a2.

📒 Files selected for processing (4)
  • internal/reportportal/analytics.go
  • internal/reportportal/analytics_test.go
  • internal/reportportal/http_server.go
  • internal/reportportal/server.go
🧰 Additional context used
📓 Path-based instructions (4)
**/*.go

📄 CodeRabbit inference engine (README.md)

MCP protocol requests must follow the JSON-RPC 2.0 specification with fields: jsonrpc, method, id, and params

Files:

  • internal/reportportal/http_server.go
  • internal/reportportal/server.go
  • internal/reportportal/analytics.go
  • internal/reportportal/analytics_test.go

⚙️ CodeRabbit configuration file

Focus on Go best practices, error handling, concurrency safety, performance, and security. Check for proper resource cleanup and context handling.

Files:

  • internal/reportportal/http_server.go
  • internal/reportportal/server.go
  • internal/reportportal/analytics.go
  • internal/reportportal/analytics_test.go
**/internal/reportportal/**/*.go

📄 CodeRabbit inference engine (README.md)

When adding new tools, create a new method in the appropriate resource file and add it to the server in the NewServer function

Files:

  • internal/reportportal/http_server.go
  • internal/reportportal/server.go
  • internal/reportportal/analytics.go
  • internal/reportportal/analytics_test.go
internal/reportportal/**

⚙️ CodeRabbit configuration file

Pay special attention to API integration patterns, error handling, data validation, and MCP protocol compliance.

Files:

  • internal/reportportal/http_server.go
  • internal/reportportal/server.go
  • internal/reportportal/analytics.go
  • internal/reportportal/analytics_test.go
**/*_test.go

⚙️ CodeRabbit configuration file

Ensure comprehensive test coverage, proper test isolation, meaningful assertions, and good test naming conventions.

Files:

  • internal/reportportal/analytics_test.go
🧠 Learnings (2)
📚 Learning: 2026-01-15T11:38:28.032Z
Learnt from: CR
Repo: reportportal/reportportal-mcp-server PR: 0
File: README.md:0-0
Timestamp: 2026-01-15T11:38:28.032Z
Learning: Applies to **/internal/reportportal/**/*.go : When adding new tools, create a new method in the appropriate resource file and add it to the server in the NewServer function

Applied to files:

  • internal/reportportal/http_server.go
  • internal/reportportal/server.go
📚 Learning: 2026-01-15T11:38:28.032Z
Learnt from: CR
Repo: reportportal/reportportal-mcp-server PR: 0
File: README.md:0-0
Timestamp: 2026-01-15T11:38:28.032Z
Learning: Applies to **/server/**/*.go : In HTTP mode, authentication tokens must be passed per-request via Authorization: Bearer header, and RP_API_TOKEN environment variable is not used

Applied to files:

  • internal/reportportal/analytics_test.go
🧬 Code graph analysis (1)
internal/reportportal/server.go (1)
internal/reportportal/analytics.go (1)
  • NewAnalytics (237-295)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Call feature Docker build / Build and export to AWS ECR
🔇 Additional comments (10)
internal/reportportal/analytics.go (5)

107-111: Well-structured lazy loading fields.

The combination of atomic.Bool for fast-path checking and sync.Mutex for slow-path protection is a solid double-checked locking pattern. The field grouping with clear comments aids maintainability.


124-157: Solid double-checked locking implementation.

The fast-path atomic check followed by mutex-protected slow-path with a second check is the correct pattern for lazy initialization in concurrent code. The retry-until-success behavior (only setting instanceIDFetched on success) is a good resilience choice.


159-227: Robust instance ID fetching with proper error handling.

Good defensive coding: context timeout, proper body close with error logging, graceful degradation returning empty string on failures. The strings.TrimSuffix on line 163 properly handles trailing slashes in the host URL.


631-637: Correct memory visibility pattern for concurrent access.

The pattern of checking the atomic flag first, then acquiring the lock to read instanceID, properly ensures memory visibility. Since the write in ensureInstanceID() sets instanceID before the atomic flag (both under lock), this read pattern is safe.


237-295: Clean extension of NewAnalytics signature.

The new rpHostURL parameter is well-documented and properly stored for lazy fetching. The initialization of instanceID as empty with lazy population is a good pattern that avoids blocking server startup.

internal/reportportal/http_server.go (1)

109-114: Correct integration with updated NewAnalytics signature.

The host URL is properly passed via config.HostURL.String(), and the empty FallbackRPToken for HTTP mode is well-documented. This enables lazy instance ID fetching in HTTP server mode.

internal/reportportal/server.go (1)

44-44: Correct parameter addition for stdio mode.

The hostUrl.String() parameter is correctly passed to NewAnalytics, enabling instance ID fetching in stdio mode as well. This maintains consistency with the HTTP server integration.

internal/reportportal/analytics_test.go (3)

152-152: Test calls updated for new signature.

All existing tests correctly pass an empty string for the new hostURL parameter, maintaining backward compatibility while the new tests cover the instance ID functionality.


1185-1254: Excellent retry behavior test coverage.

This test properly validates the retry-until-success pattern with mutex-protected counters. The verification that the fourth call uses the cached value (no additional fetch) confirms the caching behavior works correctly.


1256-1279: Good edge case coverage for empty host URL.

Validates that analytics gracefully handles missing hostURL configuration without errors or panics—the instance ID simply remains empty and events are still sent without it.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds ReportPortal instance ID parameter tracking to Google Analytics events. The instance ID is fetched from the ReportPortal /api/info endpoint and included as a parameter in GA4 events to help identify which ReportPortal instance generated the analytics data.

Changes:

  • Added lazy-loading mechanism to fetch ReportPortal instance ID from /api/info endpoint on first metrics processing
  • Updated NewAnalytics function signature to accept rpHostURL parameter for instance ID fetching
  • Added instance ID parameter to Google Analytics events when available

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
internal/reportportal/analytics.go Core implementation of instance ID fetching with retry logic and lazy loading, added instance ID parameter to GA events
internal/reportportal/server.go Updated NewAnalytics call to include host URL parameter
internal/reportportal/http_server.go Updated NewAnalytics call to include host URL parameter with comment
internal/reportportal/analytics_test.go Added comprehensive test coverage for instance ID fetching scenarios and updated all NewAnalytics calls

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/reportportal/http_server.go (1)

101-108: Potential nil pointer dereference if config.HostURL is nil.

While config.HostURL is also used on line 140 with gorp.NewClient(), the analytics initialization happens earlier. If config.HostURL is nil when analytics is enabled, calling .String() will panic.

Consider adding a defensive nil check or validating config.HostURL at the start of NewHTTPServer:

🛡️ Suggested defensive check
 func NewHTTPServer(config HTTPServerConfig) (*HTTPServer, error) {
+	// Validate required configuration
+	if config.HostURL == nil {
+		return nil, fmt.Errorf("HostURL is required")
+	}
+
 	// Set defaults
 	if config.MaxConcurrentRequests <= 0 {
🤖 Fix all issues with AI agents
In `@internal/reportportal/analytics_test.go`:
- Around line 1088-1089: The test HTTP handler ignores the error returned by
w.Write, which the linter will flag; update the two occurrences of
w.Write([]byte(response)) (and the similar call at line 1204) to explicitly
discard the error by assigning it to the blank identifier (e.g., _ =
w.Write(...)) so the return value is handled and the linter warning is silenced.
- Around line 1138-1177: The test creates a mock GA server but never points the
analytics code at it; update the test to override the GA endpoint before sending
events (e.g., set the package-level ga4EndpointURL to gaServer.URL and defer
restoring the original value), then call analytics.TrackMCPEvent(ctx,
"test_tool") and analytics.processMetrics() and assert that capturedEvents (the
slice populated by the mock server) contains at least one event and that each
event includes analytics.instanceID (or mockInstanceID); reference
TrackMCPEvent, processMetrics, ga4EndpointURL, capturedEvents and mockInstanceID
when locating the spots to change.

In `@internal/reportportal/analytics.go`:
- Around line 166-168: The apiURL construction can produce a double slash when
hostURL ends with '/', so before building apiURL in the function that sets
apiURL (the fmt.Sprintf("%s/api/info", hostURL) line) trim any trailing slash
from hostURL (e.g., use strings.TrimSuffix(hostURL, "/")) and then format the
URL; also add "strings" to the imports if missing so the fix compiles.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 73f577d and 0682a9b.

📒 Files selected for processing (4)
  • internal/reportportal/analytics.go
  • internal/reportportal/analytics_test.go
  • internal/reportportal/http_server.go
  • internal/reportportal/server.go
🧰 Additional context used
📓 Path-based instructions (3)
**/*.go

📄 CodeRabbit inference engine (README.md)

**/*.go: Build and compile the ReportPortal MCP Server Go application using go build -o reportportal-mcp-server ./cmd/reportportal-mcp-server
Set environment variables RP_HOST, RP_PROJECT, and RP_API_TOKEN for stdio mode operation, or set MCP_MODE=http with MCP_SERVER_PORT and MCP_SERVER_HOST for HTTP mode
Require Go 1.24.1 or later for building the ReportPortal MCP Server
Add new tools by creating methods in resource files and registering them in the NewServer function using s.AddTool()
Ensure all MCP requests follow JSON-RPC 2.0 specification with required fields: jsonrpc, method, id, and params
Use /mcp or /api/mcp endpoints for POST requests (MCP protocol); use /, /health, /info, /api/status, or /metrics for GET requests only

Files:

  • internal/reportportal/http_server.go
  • internal/reportportal/analytics_test.go
  • internal/reportportal/server.go
  • internal/reportportal/analytics.go

⚙️ CodeRabbit configuration file

Focus on Go best practices, error handling, concurrency safety, performance, and security. Check for proper resource cleanup and context handling.

Files:

  • internal/reportportal/http_server.go
  • internal/reportportal/analytics_test.go
  • internal/reportportal/server.go
  • internal/reportportal/analytics.go
internal/reportportal/**

⚙️ CodeRabbit configuration file

Pay special attention to API integration patterns, error handling, data validation, and MCP protocol compliance.

Files:

  • internal/reportportal/http_server.go
  • internal/reportportal/analytics_test.go
  • internal/reportportal/server.go
  • internal/reportportal/analytics.go
**/*_test.go

⚙️ CodeRabbit configuration file

Ensure comprehensive test coverage, proper test isolation, meaningful assertions, and good test naming conventions.

Files:

  • internal/reportportal/analytics_test.go
🧬 Code graph analysis (2)
internal/reportportal/analytics_test.go (2)
internal/reportportal/analytics.go (3)
  • NewAnalytics (241-294)
  • GAEvent (88-91)
  • GAPayload (94-99)
internal/reportportal/server.go (1)
  • NewServer (19-80)
internal/reportportal/server.go (1)
internal/reportportal/analytics.go (1)
  • NewAnalytics (241-294)
🔇 Additional comments (11)
internal/reportportal/server.go (1)

44-44: LGTM!

The change correctly passes the host URL string to NewAnalytics, aligning with the updated signature. The existing code already assumes hostUrl is non-nil (as seen in line 36 where it's used directly with gorp.NewClient), so no additional nil check is needed here.

internal/reportportal/analytics.go (6)

38-40: LGTM!

A 5-second timeout is reasonable for fetching instance metadata from the ReportPortal /api/info endpoint.


106-111: LGTM!

Good use of the atomic.Bool + sync.Mutex pattern for efficient double-check locking. The atomic flag enables a lock-free fast path for the common case (already fetched), while the mutex ensures thread-safe initialization.


123-156: LGTM!

The double-check locking pattern is correctly implemented:

  1. Fast-path atomic check avoids locking overhead when already fetched
  2. Lock acquisition, then re-check to prevent redundant fetches
  3. Only marks as fetched on success, enabling retry on failure

The retry-until-success design is appropriate for a non-critical metadata fetch.


202-231: LGTM!

The JSON parsing with type assertions is properly guarded. Each step validates the expected structure before proceeding, with informative warning logs for debugging when the expected fields are missing or malformed.


277-289: LGTM!

Clean initialization of the new instance ID fields. The explicit empty string for instanceID enhances readability. The HTTP client's 10-second timeout is appropriately longer than the context-based instanceIDFetchTimeout (5s), allowing the context to control the actual request deadline.


624-654: LGTM!

The instance ID integration is thread-safe:

  • ensureInstanceID() is called to trigger lazy fetch
  • The atomic flag check before reading instanceID is correct—Go's atomic operations provide the necessary memory ordering guarantees
  • Conditionally adding instanceID only when available is a clean approach
internal/reportportal/analytics_test.go (4)

6-6: LGTM!

The encoding/json import is correctly added to support the new instance ID fetching tests that decode GA payloads.


152-152: LGTM!

All NewAnalytics calls are correctly updated with the empty string fourth parameter, maintaining backward-compatible behavior in existing tests.


1179-1241: LGTM!

Excellent retry logic test coverage:

  • Validates failure on first two attempts
  • Confirms success on third attempt
  • Importantly verifies that subsequent calls use the cached value without triggering additional HTTP requests

The mutex-protected counter correctly handles potential concurrent access in the HTTP handler.


1243-1258: LGTM!

Good edge case coverage: verifies that when rpHostURL is empty, ensureInstanceID() returns early without attempting a fetch and doesn't mark the ID as fetched—maintaining correct retry behavior if a host URL is later configured.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@internal/reportportal/http_server.go`:
- Around line 75-78: The inline comment attached to the function signature for
NewHTTPServer is causing golines formatting errors; move the comment to its own
line above the function signature or delete it entirely and leave the validation
block (the HostURL nil check) as-is so the function signature is on a single
line and golines passes.
♻️ Duplicate comments (2)
internal/reportportal/analytics_test.go (1)

1142-1183: Test doesn't verify instanceID is actually sent in GA events.

The mock GA server (gaServer) is created but never used—events are still sent to the real GA4 endpoint. The test only verifies that instanceID is stored in the analytics struct, not that it appears in the event payload.

Consider either:

  1. Removing the unused gaServer and capturedEvents to clarify the test's actual scope
  2. Or injecting the mock GA endpoint URL into the analytics config to verify end-to-end behavior
♻️ Simplified test focusing on what's actually verified
 t.Run("instance ID is added to GA events", func(t *testing.T) {
-	// Create a mock GA server to capture events
-	var capturedEvents []GAEvent
-	var mu sync.Mutex
-	gaServer := httptest.NewServer(
-		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-			if r.Method == "POST" {
-				var payload GAPayload
-				if err := json.NewDecoder(r.Body).Decode(&payload); err == nil {
-					mu.Lock()
-					capturedEvents = append(capturedEvents, payload.Events...)
-					mu.Unlock()
-				}
-				w.WriteHeader(http.StatusOK)
-			}
-		}),
-	)
-	defer gaServer.Close()
-
 	// Create analytics with mock RP server
 	analytics, err := NewAnalytics("test-user", "test-secret", "", mockServer.URL)
 	require.NoError(t, err)
 	require.NotNil(t, analytics)
 	defer analytics.Stop()

-	// Override GA endpoint for testing (we need to modify the config)
 	// Track an event
 	ctx := context.Background()
 	analytics.TrackMCPEvent(ctx, "test_tool")

-	// Wait a bit for batching
-	time.Sleep(100 * time.Millisecond)
-
 	// Process metrics manually
 	analytics.processMetrics()

-	// Verify events were created with instanceID
-	// Note: In real scenario, events would be sent to GA server
-	// For this test, we verify the instanceID is stored in analytics
+	// Verify the instanceID was fetched and stored (would be included in events)
 	assert.True(t, analytics.instanceIDFetched.Load(), "Should be fetched after processing")
 	assert.Equal(t, mockInstanceID, analytics.instanceID)
 })
internal/reportportal/analytics.go (1)

649-652: Inconsistent parameter naming: use snake_case for consistency.

The parameter name instanceID uses camelCase while other parameters in the same map (custom_user_id, event_name, tool) use snake_case. For consistency and to match GA4 conventions, this should be instance_id.

🔧 Suggested fix
 			// Add instanceID if available
 			if currentInstanceID != "" {
-				params["instanceID"] = currentInstanceID
+				params["instance_id"] = currentInstanceID
 			}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d5f45a8 and 7faf1ba.

📒 Files selected for processing (4)
  • internal/reportportal/analytics.go
  • internal/reportportal/analytics_test.go
  • internal/reportportal/http_server.go
  • internal/reportportal/server.go
🧰 Additional context used
📓 Path-based instructions (4)
**/*.go

📄 CodeRabbit inference engine (README.md)

MCP protocol requests must follow the JSON-RPC 2.0 specification with fields: jsonrpc, method, id, and params

Files:

  • internal/reportportal/analytics_test.go
  • internal/reportportal/server.go
  • internal/reportportal/analytics.go
  • internal/reportportal/http_server.go

⚙️ CodeRabbit configuration file

Focus on Go best practices, error handling, concurrency safety, performance, and security. Check for proper resource cleanup and context handling.

Files:

  • internal/reportportal/analytics_test.go
  • internal/reportportal/server.go
  • internal/reportportal/analytics.go
  • internal/reportportal/http_server.go
**/internal/reportportal/**/*.go

📄 CodeRabbit inference engine (README.md)

When adding new tools, create a new method in the appropriate resource file and add it to the server in the NewServer function

Files:

  • internal/reportportal/analytics_test.go
  • internal/reportportal/server.go
  • internal/reportportal/analytics.go
  • internal/reportportal/http_server.go
**/*_test.go

⚙️ CodeRabbit configuration file

Ensure comprehensive test coverage, proper test isolation, meaningful assertions, and good test naming conventions.

Files:

  • internal/reportportal/analytics_test.go
internal/reportportal/**

⚙️ CodeRabbit configuration file

Pay special attention to API integration patterns, error handling, data validation, and MCP protocol compliance.

Files:

  • internal/reportportal/analytics_test.go
  • internal/reportportal/server.go
  • internal/reportportal/analytics.go
  • internal/reportportal/http_server.go
🧠 Learnings (2)
📚 Learning: 2026-01-15T11:38:28.032Z
Learnt from: CR
Repo: reportportal/reportportal-mcp-server PR: 0
File: README.md:0-0
Timestamp: 2026-01-15T11:38:28.032Z
Learning: Applies to **/server/**/*.go : In HTTP mode, authentication tokens must be passed per-request via Authorization: Bearer header, and RP_API_TOKEN environment variable is not used

Applied to files:

  • internal/reportportal/analytics_test.go
📚 Learning: 2026-01-15T11:38:28.032Z
Learnt from: CR
Repo: reportportal/reportportal-mcp-server PR: 0
File: README.md:0-0
Timestamp: 2026-01-15T11:38:28.032Z
Learning: Applies to **/internal/reportportal/**/*.go : When adding new tools, create a new method in the appropriate resource file and add it to the server in the NewServer function

Applied to files:

  • internal/reportportal/server.go
  • internal/reportportal/http_server.go
🧬 Code graph analysis (2)
internal/reportportal/analytics_test.go (2)
internal/reportportal/analytics.go (3)
  • NewAnalytics (237-295)
  • GAEvent (89-92)
  • GAPayload (95-100)
internal/reportportal/server.go (1)
  • NewServer (19-80)
internal/reportportal/server.go (1)
internal/reportportal/analytics.go (1)
  • NewAnalytics (237-295)
🪛 GitHub Actions: Build
internal/reportportal/http_server.go

[error] 75-75: File is not properly formatted (golines).

🪛 GitHub Check: build
internal/reportportal/http_server.go

[failure] 75-75:
File is not properly formatted (golines)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Call feature Docker build / Build and export to AWS ECR
🔇 Additional comments (15)
internal/reportportal/analytics.go (6)

39-41: LGTM! Appropriate timeout constant for instance ID fetching.

The 5-second timeout is reasonable for a network call to fetch the instance ID, balancing responsiveness with allowing for network latency.


107-112: Well-structured lazy initialization fields.

The combination of atomic.Bool for fast-path checking and sync.Mutex for protecting the actual write is a solid pattern for lazy initialization with thread safety.


124-157: Correct double-checked locking implementation.

The fast-path atomic check followed by mutex acquisition and re-check is the canonical pattern for thread-safe lazy initialization in Go. Good use of early return when rpHostURL is empty.


159-227: Robust instance ID fetching with proper resource cleanup.

Good implementation with:

  • Context-based timeout
  • Proper response body closure with error logging
  • Defensive JSON parsing with type assertions at each level

237-242: Clean signature extension and initialization.

The new rpHostURL parameter is properly stored for lazy fetching, and the shared httpClient is correctly initialized with a sensible timeout.

Also applies to: 278-290


631-637: Good fix for memory visibility on instanceID read.

Acquiring the mutex after the atomic check ensures proper memory visibility when reading instanceID. This addresses the potential race condition where another goroutine could be mid-write.

internal/reportportal/http_server.go (1)

107-112: Correct propagation of host URL to analytics.

The host URL is properly passed to NewAnalytics for instance ID fetching. Good use of .String() to convert the *url.URL to a string parameter.

internal/reportportal/analytics_test.go (7)

6-6: LGTM! Import added for JSON decoding in tests.

The encoding/json import is needed for the new instance ID fetching tests that decode JSON payloads.


152-152: All NewAnalytics call sites correctly updated.

The fourth parameter (empty string for hostURL) has been consistently added to all test invocations, maintaining backward compatibility for tests that don't need instance ID functionality.

Also applies to: 354-354, 507-507, 516-516, 572-572, 622-622, 658-658, 699-699, 729-729, 766-766, 815-815, 821-821, 896-896, 902-902, 965-965, 1027-1027


1074-1094: Well-designed mock server for instance ID testing.

The mock ReportPortal server correctly returns the expected JSON structure with the instance ID at extensions.result["server.details.instance"]. Good use of httptest.NewServer for isolation.


1096-1111: Good coverage of lazy loading behavior.

This test correctly verifies that:

  1. Instance ID is not fetched on initialization
  2. Instance ID is fetched when ensureInstanceID() is called
  3. The fetched value matches the mock server response

1113-1140: Comprehensive test of lazy fetch trigger during metrics processing.

Good verification that instance ID fetch is triggered by processMetrics() rather than TrackMCPEvent(), confirming the lazy loading design.


1185-1254: Excellent retry behavior test coverage.

This test thoroughly validates:

  1. Failed attempts don't mark instanceID as fetched
  2. Successful fetch after failures works correctly
  3. Subsequent calls use cached value (no additional HTTP requests)

The use of a counter to verify caching behavior is particularly good.


1256-1279: Good edge case coverage for empty host URL.

Verifies that when no host URL is provided, ensureInstanceID() gracefully handles the case without attempting network calls or marking the ID as fetched.

internal/reportportal/server.go (1)

44-44: Remove this comment - the nil pointer concern is invalid.

The caller in cmd/reportportal-mcp-server/main.go validates hostUrl with url.Parse() and error checking (lines 264-266) before calling NewServer, ensuring the URL is never nil. Additionally, if hostUrl were nil, the dereference would fail at line 36 (gorp.NewClient(hostUrl, token)) before reaching line 44, since Go's url.Parse() cannot return a nil pointer with a nil error. The function safely uses the validated parameter.

Likely an incorrect or invalid review comment.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@AleksandrParamonoff AleksandrParamonoff merged commit a54b766 into develop Jan 15, 2026
4 checks passed
@AleksandrParamonoff AleksandrParamonoff deleted the add-new-metric-parameter branch January 15, 2026 13:31
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