Skip to content

Conversation

@swift1337
Copy link
Contributor

@swift1337 swift1337 commented Apr 29, 2025

This PR eliminates global init() and ApplyDeadline in p2p package, improves stream mock,s and converges code paths between unit tests and real code execution

Closes #55

Summary by CodeRabbit

  • New Features

    • Introduced a new mock stream implementation for testing, providing enhanced control over simulated network stream behavior.
  • Refactor

    • Centralized and simplified deadline handling for network streams, removing global flags and improving error handling.
    • Replaced custom mock stream implementations in tests with the new standardized mock stream for consistency and maintainability.
  • Chores

    • Removed obsolete initialization and test code related to the previous deadline application logic.

@swift1337 swift1337 requested a review from a team as a code owner April 29, 2025 14:09
@swift1337 swift1337 self-assigned this Apr 29, 2025
@coderabbitai
Copy link

coderabbitai bot commented Apr 29, 2025

📝 Walkthrough

Walkthrough

The changes introduce a standardized mock implementation of the network.Stream interface for testing, replacing custom mock stream logic throughout the codebase. All references to the ApplyDeadline atomic flag are removed, and deadline application logic is centralized in a new helper function that handles both real and mock network streams. Test files are refactored to use the new mock stream and its helper methods, resulting in more concise and maintainable test code. No public interfaces are altered except for the internal removal and addition of helper functions related to stream deadline management.

Changes

File(s) Change Summary
p2p/mocks/stream.go Introduced a new mock Stream struct implementing the network.Stream interface, with concurrency-safe I/O, deadline simulation, error injection, and test helper methods.
p2p/stream_manager.go Removed the global ApplyDeadline flag and its initialization; refactored deadline logic into a new helper function applyDeadline; added error handling for mocknet environments via isMockNetError.
p2p/stream_manager_test.go Removed the custom MockNetworkStream and replaced all usages with the new mocks.Stream; updated test logic to use new helper methods and improved assertions; removed all references to ApplyDeadline.
p2p/party_coordinator_test.go Removed the init function that set ApplyDeadline.Store(false); no other logic changed.
keysign/signature_notifier_test.go Removed all references to p2p.ApplyDeadline.Store(false) and the import of the p2p package; no other test logic modified.

Sequence Diagram(s)

sequenceDiagram
    participant Test as Test Suite
    participant MockStream as mocks.Stream
    participant StreamManager as StreamManager

    Test->>MockStream: NewStream(t)
    Test->>MockStream: MustWrite(data)
    Test->>StreamManager: ReadStreamWithBuffer(MockStream, ...)
    StreamManager->>MockStream: applyDeadline (SetReadDeadline)
    alt Deadline error (mocknet)
        StreamManager->>MockStream: isMockNetError(err)
        StreamManager-->>Test: Continue (ignore error)
    else Deadline error (real)
        StreamManager->>MockStream: Reset()
        StreamManager-->>Test: Return error
    end
    StreamManager->>MockStream: Read()
    StreamManager-->>Test: Return data or error
Loading

This diagram illustrates the new, centralized deadline handling and error tolerance for both real and mock streams during read operations in tests.

✨ Finishing Touches
  • 📝 Generate Docstrings

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.
    • Generate unit testing code for this file.
    • 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. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

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

Documentation and Community

  • 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

@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 (3)
p2p/mocks/stream.go (2)

43-44: Consider using a larger range for random stream IDs.

The current implementation limits stream IDs to values under 10,000, which could potentially lead to ID collisions in large-scale tests with many mock streams.

-		id:       rand.Uint64() % 10_000,
+		id:       rand.Uint64(),

1-218: Consider adding a Reset method to clear buffer contents.

The mock implementation is comprehensive but lacks a method to reset the buffer contents between test cases without creating a new instance.

Consider adding a method like:

func (s *Stream) Reset() error {
	s.mu.Lock()
	defer s.mu.Unlock()
	
	s.buffer.Reset()
	s.readDeadline = time.Time{}
	s.writeDeadline = time.Time{}
	s.errSetReadDeadLine = false
	s.errSetWriteDeadLine = false
	s.errRead = false
	
	return nil
}
p2p/stream_manager_test.go (1)

16-106: Consider adding boundary test cases.

The test cases cover basic scenarios, but could be enhanced with boundary conditions such as empty payloads or exactly at the MaxPayload size.

Add test cases for:

  1. Empty payload (0 bytes)
  2. Payload exactly at MaxPayload
  3. Payload exceeding MaxPayload by 1 byte

Example test case:

{
	name:           "payload at max size",
	expectedLength: MaxPayload - PayloadHeaderLen,
	expectError:    false,
	streamProvider: func() network.Stream {
		s := mocks.NewStream(t)
		buf := make([]byte, PayloadHeaderLen)
		binary.LittleEndian.PutUint32(buf, MaxPayload - PayloadHeaderLen)

		s.MustWrite(buf)
		s.MustWrite(bytes.Repeat([]byte("a"), int(MaxPayload - PayloadHeaderLen)))

		return s
	},
},
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 032c922 and a94b765.

📒 Files selected for processing (5)
  • keysign/signature_notifier_test.go (0 hunks)
  • p2p/mocks/stream.go (1 hunks)
  • p2p/party_coordinator_test.go (0 hunks)
  • p2p/stream_manager.go (4 hunks)
  • p2p/stream_manager_test.go (7 hunks)
💤 Files with no reviewable changes (2)
  • p2p/party_coordinator_test.go
  • keysign/signature_notifier_test.go
🧰 Additional context used
🧬 Code Graph Analysis (1)
p2p/stream_manager.go (1)
p2p/mocks/stream.go (1)
  • Stream (19-34)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test go 1.22
🔇 Additional comments (13)
p2p/mocks/stream.go (3)

57-86: Well-implemented blocking I/O simulation with deadlines.

The implementation correctly simulates blocking I/O with timeout behavior using goroutines and channels, properly handling both immediate reads and deadline-based reads.


93-122: Consistent implementation with Read method.

The Write method follows the same pattern as the Read method, ensuring consistency in the blocking I/O simulation with deadlines.


124-127: Helpful test utility methods.

These convenience methods integrate well with the testing framework and help reduce boilerplate in test code.

p2p/stream_manager.go (4)

208-210: Good refactoring of deadline application logic.

Replacing the direct deadline application with a centralized helper function improves code organization and maintainability.


243-244: Consistent handling of write deadlines.

The same approach is correctly applied to write deadlines, ensuring consistency in the codebase.


266-295: Well-designed error tolerance with proper resource cleanup.

The applyDeadline function correctly handles errors by resetting the stream when needed and includes special handling for mocknet errors. The comments clearly explain the behavior.


297-320: Robust error detection for mocknet streams.

The isMockNetError function properly identifies errors from mocknet streams that don't support deadlines, with thorough validation of error properties.

Consider adding a unit test for this function to ensure it correctly identifies mocknet errors and rejects other types of errors:

func TestIsMockNetError(t *testing.T) {
	tests := []struct {
		name     string
		err      error
		expected bool
	}{
		{
			name:     "nil error",
			err:      nil,
			expected: false,
		},
		{
			name:     "non-OpError",
			err:      errors.New("random error"),
			expected: false,
		},
		{
			name:     "mocknet error",
			err:      &net.OpError{Op: "set", Net: "pipe", Err: errors.New("deadline not supported")},
			expected: true,
		},
		{
			name:     "other OpError",
			err:      &net.OpError{Op: "read", Net: "tcp", Err: errors.New("connection reset")},
			expected: false,
		},
	}
	
	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			result := isMockNetError(tc.err)
			require.Equal(t, tc.expected, result)
		})
	}
}
p2p/stream_manager_test.go (6)

11-11: Good addition of mocks import.

The import of the new mock package aligns with the refactoring to use a standardized mock implementation.


29-36: Simplified stream creation with the new mock.

Using the new standardized mock stream simplifies the test code and improves clarity.


44-53: Better error simulation with dedicated methods.

The error simulation is now more explicit with the dedicated ErrSetReadDeadline method.


97-103: Improved error assertion pattern.

Using require.Error and early return for error cases improves readability and makes test failures more obvious.


111-112: Type correction in interface.

The function signature correctly specifies the return type as *mocks.Stream instead of a generic network.Stream, making the tests more type-safe.


154-162: Good refactoring with helper function.

The addition of the hasStream helper function improves readability and simplifies stream presence checking.

Copy link
Contributor

@ws4charlie ws4charlie left a comment

Choose a reason for hiding this comment

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

looks good. BTW, what issue is this PR solving?

@swift1337
Copy link
Contributor Author

swift1337 commented Apr 30, 2025

looks good. BTW, what issue is this PR solving?

Code paths for unit tests and real-world usage diverged. Also global bool toggle could be changed by any LoC in the project

@swift1337 swift1337 merged commit 14f84bf into master May 1, 2025
6 checks passed
@swift1337 swift1337 deleted the refactor/deadlines branch May 1, 2025 09:46
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.

Unify deadlines across env (unit test / real exec)

3 participants