Commit graph

15 commits

Author SHA1 Message Date
Nick Misasi
01643af641 debug: add extensive logging to trace hook registration flow
Go side:
- Log hooks returned by Implemented()
- Log each hook name -> ID mapping
- Log OnActivate implementation status
- Log OnActivate call flow

Python side:
- Log Implemented() return value
- Log OnActivate gRPC receipt and handler invocation

This is temporary debug logging to diagnose why OnActivate
isn't being called for Python plugins.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 09:12:22 -05:00
Nick Misasi
448be3350e bench(10-03): add Python SDK benchmark tests
Create comprehensive benchmark tests measuring Python SDK overhead:

API Call Benchmarks:
- GetServerVersion: baseline gRPC round-trip
- GetUser: entity retrieval with wrapper conversion
- GetChannel: another entity pattern

Wrapper Conversion Benchmarks:
- User.from_proto / User.to_proto
- Post.from_proto
- Channel.from_proto

Hook Decorator Benchmarks:
- Hook decorator application overhead
- get_hook_name lookup (attribute access)
- is_hook_handler check

Uses simple timing with time.perf_counter() for compatibility
(pytest-benchmark not required). Reports mean, median, stdev,
min, max, and ops/sec for each benchmark.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 15:43:42 -05:00
Nick Misasi
324fa65c95 test(10-02): add Python integration tests for gRPC round-trip
Create end-to-end integration tests proving Python SDK communicates
correctly with gRPC servers:

API Round-trip Tests:
- test_get_server_version_round_trip: Version API call
- test_get_system_install_date_round_trip: Install date API call
- test_get_user_round_trip: User lookup with entity serialization
- test_multiple_api_calls_in_sequence: Sequential API calls

Error Propagation Tests:
- test_not_found_error: NOT_FOUND -> NotFoundError mapping
- test_permission_denied_error: PERMISSION_DENIED mapping
- test_app_error_in_response: AppError -> PluginAPIError conversion
- test_error_recovery: Client recovery after errors

Hook Invocation Tests:
- test_implemented_returns_hooks: Implemented RPC verification
- test_lifecycle_hooks_invocation: OnActivate/OnDeactivate chain
- test_message_hook_allows_post: Normal message passthrough
- test_message_hook_rejects_spam: Message rejection
- test_message_hook_modifies_post: Message modification

Complex Scenario Tests:
- test_concurrent_api_calls: Multi-threaded API calls
- test_sequential_connect_disconnect: Connection lifecycle
- test_large_message_handling: Large payload handling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 15:36:16 -05:00
Nick Misasi
11ddd32a8c test(08-02): add tests for response streaming, flush, and invalid status codes
Go tests:
- TestInvalidStatusCode_TooLow: verify status 42 returns 500 error
- TestInvalidStatusCode_TooHigh: verify status 1000 returns 500 error
- TestInvalidStatusCode_DoesNotPanic: ensure no panic for any invalid code
- TestFlush_WithFlusher: verify flush calls http.Flusher.Flush()
- TestFlush_WithoutFlusher: verify flush doesn't panic without Flusher
- TestFlushGracefulDegradation: mirror plugin/http_test.go behavior
- TestStreamResponseBody_WithFlush: verify flush flags processed in stream
- TestEarlyResponse_CancelsRequestSend: verify early response stops sender

Python tests:
- test_flush_method_exists: verify flush() is callable
- test_flush_applies_to_last_write: verify retroactive flush
- test_flush_applies_to_next_write_when_empty: verify pre-write flush
- test_multiple_writes_with_selective_flush: verify selective flushing
- test_streaming_response_chunks: verify multiple writes = multiple messages
- test_empty_body_response: verify no-body response handling
- test_response_headers_in_first_message: verify header placement

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 14:40:41 -05:00
Nick Misasi
503ab08cbc test(08-01): add comprehensive tests for ServeHTTP streaming
Add tests for both Go and Python ServeHTTP implementations covering:
- Body chunking behavior (small, exact, multiple, large bodies)
- Context cancellation during body streaming
- Header conversion utilities
- HTTPRequest/HTTPResponseWriter helper classes
- Request body assembly from multiple chunks
- Error handling (500 for handler errors, 404 for missing handler)

Go tests:
- TestChunking_* for body chunking scenarios
- TestConvertHTTPHeaders for header conversion
- TestBuildRequestInit for request metadata building
- TestWriteResponseHeaders for response header writing
- TestContextCancellation_DuringBodyRead for cancellation

Python tests:
- TestHTTPRequest for request wrapper class
- TestHTTPResponseWriter for response writer class
- TestHeaderConversion for proto<->dict conversion
- TestServeHTTPServicer for gRPC servicer behavior
- TestChunkingBehavior for body assembly
- TestCancellation for request cancellation

Also:
- Fixed sendRequest to properly set body_complete flag on EOF
- Added ServeHTTP to HookName enum

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 14:31:30 -05:00
Nick Misasi
4813f47b3f test(07-03): add comprehensive tests for remaining hooks
- Add test_hooks_command_config.py: ExecuteCommand and
  ConfigurationWillBeSaved hook tests
- Add test_hooks_user_channel.py: User lifecycle, channel/team,
  and SAML login hook tests
- Add test_hooks_notifications.py: Reaction, notification, and
  preferences hook tests
- Add test_hooks_system.py: System, WebSocket, cluster, shared
  channels, and support data hook tests
- All 65 new tests verify correct hook semantics including:
  - Fire-and-forget vs return-value hooks
  - Rejection string semantics for UserWillLogIn
  - Modify/reject semantics for notifications
  - Error handling for all hook types

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 11:41:41 -05:00
Nick Misasi
ab345d7e57 test(07-02): add gRPC integration tests for hook servicer
- Add test_hooks_grpc_integration.py with in-process gRPC tests:
  - Test Implemented RPC returns correct hook list
  - Test lifecycle hooks (OnActivate, OnDeactivate, OnConfigurationChange)
  - Test MessageWillBePosted allow/reject/modify scenarios
  - Test notification hooks (MessageHasBeenPosted)
  - Test activation failure propagation via response.error
  - Test async handlers work through gRPC
- Fix lifecycle hooks to encode errors in response, not gRPC status
  - Remove context parameter from runner.invoke() for lifecycle hooks
  - Ensures activation failures are returned as AppError, not gRPC error

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 11:27:41 -05:00
Nick Misasi
6392b981fe test(07-02): add tests for lifecycle and message hook semantics
- Add test_hooks_lifecycle.py with tests for:
  - Implemented RPC returning correct hook list
  - OnActivate success/failure propagation
  - OnDeactivate best-effort semantics
  - OnConfigurationChange error handling
- Add test_hooks_messages.py with tests for:
  - MessageWillBePosted allow/reject/modify/dismiss semantics
  - MessageWillBeUpdated with old/new post handling
  - Notification hooks (Posted/Updated/Deleted)
  - MessagesWillBeConsumed list filtering/modification
- Fix @hook decorator to preserve async handlers
  - Use separate async wrapper for coroutine functions
  - Enables proper async detection in hook runner

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 11:26:03 -05:00
Nick Misasi
46a931d49d test(07-01): add plugin bootstrap smoke tests
- Test handshake line format matches go-plugin protocol
- Test server starts on ephemeral port
- Test health check responds with SERVING status
- Test RuntimeConfig loading from environment
- Add integration test for full plugin lifecycle

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 11:18:43 -05:00
Nick Misasi
cf89dd1b32 test(07-01): add hook runner unit tests
- Test sync and async handler execution
- Test timeout handling with HookTimeoutError
- Test exception wrapping in HookInvocationError
- Test gRPC status code conversion
- Test HookRunner class invocation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 11:18:38 -05:00
Nick Misasi
9cbd52e2ba test(07-01): add hook registry unit tests
- Test hook decorator with enum, string, and inferred names
- Test Plugin base class hook discovery via __init_subclass__
- Test duplicate registration error
- Test implemented_hooks() returns sorted canonical names
- Test invoke_hook() and get_hook_handler() methods

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 11:18:33 -05:00
Nick Misasi
3974d55f20 test(06-03): add unit tests for Post/File/KV API methods
Add comprehensive tests (34 test cases) covering:
- Wrapper dataclass conversions (Post, Reaction, PostList, FileInfo)
- Post client methods (create, get, update, delete, ephemeral, reactions)
- File client methods (info, content, upload, link)
- KV store methods (set, get, delete, list, atomic operations)
- Error handling (NotFoundError, ValidationError, gRPC errors)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 10:06:36 -05:00
Nick Misasi
529e8d9a05 test(06-02): add unit tests for User/Team/Channel API methods
Add comprehensive test suite covering:

Wrapper type tests:
- User, Team, Channel from_proto/to_proto round-trips
- UserStatus, TeamMember, ChannelMember conversions

Client method tests:
- User: get_user success, not found error, gRPC error, create_user
- Team: get_team, create_team_member, get_teams_for_user
- Channel: get_channel, add_channel_member, get_direct_channel, search

Error handling tests:
- PermissionDeniedError (HTTP 403)
- ValidationError (HTTP 400)
- AlreadyExistsError (HTTP 409)

All 21 tests use mocked stubs for fast execution.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 09:55:18 -05:00
Nick Misasi
6043b7906a test(06-01): add smoke tests for codegen and client
Add comprehensive smoke tests:
- test_codegen_imports.py: verify all generated modules import correctly
- test_client_smoke.py: test client lifecycle, error mapping, and RPC calls
- Tests use in-process fake gRPC server for integration testing
- 42 tests passing covering imports, message creation, and error handling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 14:45:01 -05:00
Nick Misasi
3cf6e36477 feat(06-01): add Python SDK package scaffold with pyproject.toml
Create the foundational Python SDK package structure:
- pyproject.toml with project metadata and dependencies
- src/mattermost_plugin/ package with src layout
- Configured for Python >=3.9 with grpcio and protobuf deps
- Dev dependencies include grpcio-tools, mypy-protobuf, pytest

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 14:44:29 -05:00