Skip to content

Conversation

@tisnik
Copy link
Contributor

@tisnik tisnik commented Aug 19, 2025

Description

LCORE-467: TCP ports type should be positive int

Type of change

  • Refactor
  • New feature
  • Bug fix
  • CVE fix
  • Optimization
  • Documentation Update
  • Configuration Update
  • Bump-up service version
  • Bump-up dependent library
  • Bump-up library or tool used for development (does not change the final image)
  • CI configuration change
  • Konflux configuration change
  • Unit tests improvement
  • Integration tests improvement
  • End to end tests improvement

Related Tickets & Documents

  • Related Issue #LCORE-467

Summary by CodeRabbit

  • New Features
    • Stricter configuration validation: ports and worker counts now require positive integers, rejecting negative or zero values.
  • Bug Fixes
    • Unified validation feedback for non-positive inputs (e.g., “Input should be greater than 0”).
    • Preserved upper-bound port checks (values >65535 still rejected).
  • Documentation
    • Configuration docs updated to reflect positive-integer constraints for ports and workers.
  • Tests
    • Unit tests adjusted to expect the new validation behavior and messages.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 19, 2025

Warning

Rate limit exceeded

@tisnik has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 8 minutes and 9 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 3ed2bf6 and 501484a.

⛔ Files ignored due to path filters (1)
  • docs/config.png is excluded by !**/*.png
📒 Files selected for processing (3)
  • docs/config.puml (2 hunks)
  • src/models/config.py (3 hunks)
  • tests/unit/models/test_config.py (2 hunks)

Walkthrough

Type constraints were tightened: ports and workers changed to PositiveInt in src/models/config.py. docs/config.puml now shows Annotated types for those fields. Tests were updated to expect Pydantic ValidationError for negative values. Port upper-bound validation (<= 65535) remains.

Changes

Cohort / File(s) Summary
Config model types
src/models/config.py
Imported PositiveInt; changed PostgreSQLDatabaseConfiguration.port, ServiceConfiguration.port, and ServiceConfiguration.workers from int to PositiveInt; removed redundant lower-bound checks; retained port upper-bound validation (<= 65535).
Docs UML update
docs/config.puml
Updated field annotations to Annotated for port (PostgreSQLDatabaseConfiguration, ServiceConfiguration) and workers (ServiceConfiguration).
Unit tests adjustments
tests/unit/models/test_config.py
Updated tests to expect Pydantic ValidationError messages for negative port/workers ("Input should be greater than 0"); preserved upper-bound port ValueError test for >65535.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User / Config Loader
  participant M as Pydantic Model
  participant F as Field Type (PositiveInt)
  participant B as Additional Validators

  U->>M: Instantiate ServiceConfiguration / PostgreSQLDatabaseConfiguration
  activate M
  M->>F: Validate numeric fields as PositiveInt
  Note right of F #D6EAF8: Enforces value > 0 (Pydantic)
  F-->>M: Success or ValidationError
  alt PositiveInt OK
    M->>B: Run additional checks (e.g., port <= 65535)
    B-->>M: OK or ValueError
  end
  M-->>U: Model instance or exception
  deactivate M
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A soft hop, a careful twitch,
Ports now spring from positive stitch.
Workers count up, no negatives found,
Validators guard the garden ground.
I nibble a carrot — tests green and sound. 🥕

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@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

🧹 Nitpick comments (4)
docs/config.puml (1)

76-76: Doc types are ambiguous: replace bare "Annotated" with a concrete type (PositiveInt).

The PlantUML shows Annotated without parameters, which is not informative and diverges from code (PositiveInt). Prefer reflecting the actual constraint to avoid confusion.

Apply this diff to the UML:

-  port : Annotated
+  port : PositiveInt
-  port : Annotated
+  port : PositiveInt
-  workers : Annotated
+  workers : PositiveInt

Also applies to: 90-90, 92-92

src/models/config.py (3)

61-61: Port as PositiveInt: good change; consider consolidating upper-bound at the type level.

Current upper-bound checks for ports (<= 65535) are performed in validators. As an optional improvement and to DRY constraints across Service/PostgreSQL, introduce a shared Port type alias with both bounds enforced by the type.

Here’s a minimal refactor:

  • Add at the imports (top of file):
-from pydantic import BaseModel, model_validator, FilePath, AnyHttpUrl, PositiveInt
+from pydantic import BaseModel, model_validator, FilePath, AnyHttpUrl, PositiveInt, Field
+from typing import Annotated
  • Define a reusable alias near the top-level (above the first model):
# Reusable port type: >0 and <=65535
Port = Annotated[PositiveInt, Field(le=65535)]
  • Use it in models:
-    port: PositiveInt = 5432
+    port: Port = 5432

With this, you can drop the explicit port upper-bound checks in validators for both classes.


125-125: Service port as PositiveInt: consistent with DB port; consider the shared Port alias here too.

Align ServiceConfiguration.port with the same Port alias so both locations share identical constraints and error messaging.

Apply:

-    port: PositiveInt = 8080
+    port: Port = 8080

127-127: Workers as PositiveInt: redundant manual lower-bound check below can be removed.

PositiveInt enforces workers > 0 at parsing time; the later validator still checks < 1. That check is now dead code and can be confusing.

Apply this diff to simplify the validator:

     def check_service_configuration(self) -> Self:
         """Check service configuration."""
-        if self.port > 65535:
-            raise ValueError("Port value should be less than 65536")
-        if self.workers < 1:
-            raise ValueError("Workers must be set to at least 1")
+        if self.port > 65535:
+            raise ValueError("Port value should be less than 65536")
         return self

If you adopt the Port alias suggestion, the upper-bound port check can be removed as well.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d6a0767 and c942c4c.

⛔ Files ignored due to path filters (1)
  • docs/config.png is excluded by !**/*.png
📒 Files selected for processing (4)
  • docs/config.puml (2 hunks)
  • src/models/config.py (3 hunks)
  • src/models/response_classes (1 hunks)
  • tests/unit/models/test_config.py (2 hunks)
⏰ 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). (2)
  • GitHub Check: build-pr
  • GitHub Check: e2e_tests
🔇 Additional comments (1)
src/models/config.py (1)

6-6: LGTM: PositiveInt import is correct and scoped appropriately.

Importing PositiveInt from pydantic aligns with the refactor goal and enables built-in lower-bound validation.

Comment on lines 1 to 12
class ProviderHealthStatus(BaseModel):
class ReadinessResponse(BaseModel):
class LivenessResponse(BaseModel):
class NotAvailableResponse(BaseModel):
class FeedbackResponse(BaseModel):
class StatusResponse(BaseModel):
class UnauthorizedResponse(BaseModel):
class ForbiddenResponse(UnauthorizedResponse):
class ConversationResponse(BaseModel):
class ConversationDeleteResponse(BaseModel):
class ConversationDetails(BaseModel):
class ConversationsListResponse(BaseModel):
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

NameError risk: BaseModel is used but never imported.

This module will fail to import because BaseModel is undefined. Add the import.

Apply this diff:

+from pydantic import BaseModel
+
 class ProviderHealthStatus(BaseModel):
 class ReadinessResponse(BaseModel):
 class LivenessResponse(BaseModel):
 class NotAvailableResponse(BaseModel):
 class FeedbackResponse(BaseModel):
 class StatusResponse(BaseModel):
 class UnauthorizedResponse(BaseModel):
 class ForbiddenResponse(UnauthorizedResponse):
 class ConversationResponse(BaseModel):
 class ConversationDeleteResponse(BaseModel):
 class ConversationDetails(BaseModel):
 class ConversationsListResponse(BaseModel):
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
class ProviderHealthStatus(BaseModel):
class ReadinessResponse(BaseModel):
class LivenessResponse(BaseModel):
class NotAvailableResponse(BaseModel):
class FeedbackResponse(BaseModel):
class StatusResponse(BaseModel):
class UnauthorizedResponse(BaseModel):
class ForbiddenResponse(UnauthorizedResponse):
class ConversationResponse(BaseModel):
class ConversationDeleteResponse(BaseModel):
class ConversationDetails(BaseModel):
class ConversationsListResponse(BaseModel):
from pydantic import BaseModel
class ProviderHealthStatus(BaseModel):
class ReadinessResponse(BaseModel):
class LivenessResponse(BaseModel):
class NotAvailableResponse(BaseModel):
class FeedbackResponse(BaseModel):
class StatusResponse(BaseModel):
class UnauthorizedResponse(BaseModel):
class ForbiddenResponse(UnauthorizedResponse):
class ConversationResponse(BaseModel):
class ConversationDeleteResponse(BaseModel):
class ConversationDetails(BaseModel):
class ConversationsListResponse(BaseModel):
🤖 Prompt for AI Agents
In src/models/response_classes around lines 1 to 12, the classes inherit from
BaseModel but BaseModel is not imported, causing a NameError on import; add the
appropriate import statement (e.g., "from pydantic import BaseModel") at the top
of the file so BaseModel is defined before these class declarations.

💡 Verification agent

🧩 Analysis chain

Clarify module packaging and intent; add minimal structure or postpone.

  • File path lacks a .py extension in this diff preview; ensure it’s a Python module (e.g., response_classes.py) or a package with an init.py. Otherwise, imports will fail.
  • All models are empty. If they’re placeholders, either:
    • Add docstrings and minimal fields (status/message) to justify their existence and make tests possible, or
    • Drop the file until it’s needed to avoid dead code.

To verify packaging, you can run:

Optionally, a minimal usable shape for a couple of classes:

from pydantic import BaseModel

class StatusResponse(BaseModel):
    status: str  # e.g., "ok"

class UnauthorizedResponse(BaseModel):
    detail: str = "Unauthorized"

class ForbiddenResponse(UnauthorizedResponse):
    detail: str = "Forbidden"

🏁 Script executed:

#!/bin/bash
# Ensure this is a Python module or package
fd -a 'response_classes*' -d 3 src | nl -ba

# If it's a package directory, ensure __init__.py exists:
fd -a '__init__.py' -d 4 src | nl -ba

Length of output: 269


🏁 Script executed:

#!/bin/bash
# Locate any file or directory named response_classes within src (up to 3 levels deep)
find src -maxdepth 3 \( -type f -iname "response_classes*.py" -o -type d -iname "response_classes*" \)

# List all __init__.py files to verify Python packages
find src -type f -iname "__init__.py"

Length of output: 381


🏁 Script executed:

#!/bin/bash
# List all files under src/models containing 'response' in their filename
find src/models -type f -iname '*response*'

# Search for 'ProviderHealthStatus' class definition in the repository
rg -nP --type py "class\s+ProviderHealthStatus\b" -C2 || echo "No matches found"

Length of output: 394


Fix Python module packaging and address duplicate empty models

The file src/models/response_classes is currently a plain file without a .py extension or an __init__.py, so it won’t be importable. Moreover, all of its classes are empty and duplicate definitions already exist in src/models/responses.py.

Please resolve the following before merging:

• Rename or convert src/models/response_classes into a proper Python module:
– If it’s meant to be a single file, rename to response_classes.py.
– If it’s a package directory, add an __init__.py and move the classes inside.
• Eliminate duplication by consolidating or removing empty placeholders—classes like ProviderHealthStatus, StatusResponse, etc., are already defined (with fields/docstrings) in src/models/responses.py.
• If you need placeholders, add minimal fields or docstrings to justify each model; otherwise, drop unused definitions.

🤖 Prompt for AI Agents
In src/models/response_classes around lines 1 to 12, the file is not a proper
Python module (missing .py or __init__.py) and it contains empty duplicate model
classes already defined in src/models/responses.py; fix by converting this into
a proper module (rename to response_classes.py or make a package directory with
__init__.py), then reconcile duplicates by removing or consolidating these empty
placeholders—either import the canonical classes from src/models/responses.py or
delete the redundant empty definitions, and if any placeholder must remain add
minimal fields or docstrings to justify them.

@tisnik tisnik force-pushed the lcore-467-tcp-ports-configuration branch from c942c4c to 3ed2bf6 Compare August 19, 2025 07:33
Copy link
Contributor

@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: 0

♻️ Duplicate comments (2)
tests/unit/models/test_config.py (2)

51-52: Switched to ValidationError for PositiveInt: LGTM

Updating the assertion to expect pydantic.ValidationError aligns with using PositiveInt on the port field and resolves the earlier review concern.


60-61: Switched to ValidationError for PositiveInt: LGTM

Updating the assertion to expect pydantic.ValidationError for workers is correct given the PositiveInt change.

🧹 Nitpick comments (1)
tests/unit/models/test_config.py (1)

49-56: Make validation assertions more robust to pydantic message changes

Matching the exact error message string can be brittle across pydantic versions. Consider asserting on error type/code and location instead.

Example pattern:

with pytest.raises(ValidationError) as excinfo:
    ServiceConfiguration(port=-1)
err = excinfo.value.errors()[0]
assert err["type"] == "greater_than"
assert err["loc"] == ("port",)
assert err["ctx"]["gt"] == 0

And similarly for workers:

with pytest.raises(ValidationError) as excinfo:
    ServiceConfiguration(workers=-1)
err = excinfo.value.errors()[0]
assert err["type"] == "greater_than"
assert err["loc"] == ("workers",)
assert err["ctx"]["gt"] == 0

Also applies to: 58-62

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c942c4c and 3ed2bf6.

⛔ Files ignored due to path filters (1)
  • docs/config.png is excluded by !**/*.png
📒 Files selected for processing (3)
  • docs/config.puml (2 hunks)
  • src/models/config.py (3 hunks)
  • tests/unit/models/test_config.py (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/models/config.py
  • docs/config.puml
⏰ 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). (2)
  • GitHub Check: build-pr
  • GitHub Check: e2e_tests

@tisnik
Copy link
Contributor Author

tisnik commented Aug 19, 2025

@CodeRabbit fullreview

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 19, 2025

@tisnik I'll conduct a full review of the changes in this PR that updates TCP port types to use positive integers.

This review will cover:

  • The refactoring from int to PositiveInt in configuration models
  • Removal of manual validation checks in favor of Pydantic's built-in validation
  • Updates to test cases and documentation
  • Overall code quality and consistency improvements
✅ Actions performed

Full review triggered.

Copy link
Contributor

@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: 0

🧹 Nitpick comments (4)
src/models/config.py (2)

138-139: Redundant workers lower-bound check (unreachable with PositiveInt)

workers is PositiveInt, so < 1 is impossible. This validator branch will never run; consider removing for clarity.

Apply this diff to drop the dead code:

     if self.port > 65535:
         raise ValueError("Port value should be less than 65536")
-    if self.workers < 1:
-        raise ValueError("Workers must be set to at least 1")
     return self

70-77: DRY the port upper-bound check across models using a shared constrained type

You duplicate the port > 65535 check in both PostgreSQLDatabaseConfiguration and ServiceConfiguration. Consider a single constrained type to encode both bounds at the type level and remove these manual checks. Benefits: consistent behavior (ValidationError), no duplication, clearer docs.

Option A (minimal change): Keep PositiveInt and add Field(le=65535) via a type alias.

  • Define once near imports (outside the selected range):
from typing import Annotated
from pydantic import Field

Port = Annotated[PositiveInt, Field(le=65535)]
  • Then change the fields (within current ranges):
-    port: PositiveInt = 5432
+    port: Port = 5432
-    port: PositiveInt = 8080
+    port: Port = 8080
  • Remove the duplicated upper-bound checks:
     if self.port > 65535:
-        raise ValueError("Port value should be less than 65536")
+        raise ValueError("Port value should be less than 65536")

Alternatively, if you adopt Port as above, drop these two if self.port > 65535 branches entirely:

-        if self.port > 65535:
-            raise ValueError("Port value should be less than 65536")

And:

-        if self.port > 65535:
-            raise ValueError("Port value should be less than 65536")

Option B (one-shot): Use Annotated[int, Field(gt=0, le=65535)] for full bounds without PositiveInt. Similar edits apply.

Also applies to: 136-137

tests/unit/models/test_config.py (1)

54-55: Confirm exception type for upper-bound port validation

Given this check is in a model_validator(mode="after") and raises ValueError, Pydantic may surface a ValidationError at construction time (common in v2). Consider standardizing on ValidationError here as well, or verify locally that ValueError is indeed raised.

If you decide to standardize (recommended), apply:

-    with pytest.raises(ValueError, match="Port value should be less than 65536"):
+    with pytest.raises(ValidationError, match="Port value should be less than 65536"):
         ServiceConfiguration(port=100000)

Even better, if you move the upper-bound to a constrained type (Annotated/Field), the exception will naturally be a ValidationError.

docs/config.puml (1)

76-76: Documentation: use PositiveInt (or explicit constraint) instead of generic Annotated

The code uses PositiveInt for these fields; showing only “Annotated” in the diagram loses fidelity. Consider reflecting the concrete type (or the full constraint if you adopt an Annotated alias with upper bound).

Minimal alignment with current code:

-  port : Annotated
+  port : PositiveInt
-  port : Annotated
+  port : PositiveInt
-  workers : Annotated
+  workers : PositiveInt

If you later encode the upper bound at the type level, you could render it as:

  • port : Annotated[int, gt=0, le=65535]
    or simply annotate with a note/stereotype to avoid cluttering the diagram.

Also applies to: 90-90, 92-92

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d6a0767 and 3ed2bf6.

⛔ Files ignored due to path filters (1)
  • docs/config.png is excluded by !**/*.png
📒 Files selected for processing (3)
  • docs/config.puml (2 hunks)
  • src/models/config.py (3 hunks)
  • tests/unit/models/test_config.py (2 hunks)
🔇 Additional comments (3)
src/models/config.py (1)

6-6: Good move: tightening types to PositiveInt for ports and workers

Adopting PositiveInt removes manual lower-bound checks and pushes invalid inputs to Pydantic’s field-level validation. Defaults (5432, 8080, 1) remain valid. No issues spotted.

Also applies to: 61-61, 125-128

tests/unit/models/test_config.py (2)

51-52: LGTM: negative port now expects ValidationError

This aligns with PositiveInt behavior and Pydantic v2 field validation.


60-61: LGTM: negative workers now expects ValidationError

Matches PositiveInt semantics; good update.

@tisnik tisnik force-pushed the lcore-467-tcp-ports-configuration branch from 3ed2bf6 to 501484a Compare August 19, 2025 07:47
@tisnik tisnik merged commit 6182cd7 into lightspeed-core:main Aug 19, 2025
18 checks passed
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.

1 participant