# Bridge Service Tests This directory contains comprehensive tests for the bridge service located at `cmd/bridge/main.go`. ## Test Structure ``` tests/bridge/ ├── bridge_test.go # Core bridge functions extracted for testing ├── mqtt_handler_test.go # Unit tests for MQTT message handling ├── event_loop_test.go # Unit tests for event loop logic ├── integration_test.go # Integration tests with real Kafka ├── testutil.go # Test utilities and helper functions └── README.md # This file ``` ## Test Categories ### 1. Unit Tests (`mqtt_handler_test.go`) Tests the MQTT handler function that processes incoming beacon readings: - **TestMQTTHandler_SingleReading**: Tests handling of a single beacon reading - **TestMQTTHandler_MultipleReadings**: Tests handling of multiple readings in one message - **TestMQTTHandler_GatewayTypeSkipped**: Verifies Gateway-type readings are filtered out - **TestMQTTHandler_UnknownBeaconSkipped**: Verifies unknown beacons are skipped - **TestMQTTHandler_InvalidJSON**: Tests error handling for invalid JSON - **TestMQTTHandler_HostnameExtraction**: Tests hostname extraction from various topic formats - **TestMQTTHandler_PreservesRawData**: Verifies raw data is preserved correctly ### 2. Event Loop Tests (`event_loop_test.go`) Tests the main event loop logic: - **TestEventLoop_ApiUpdate_POST**: Tests adding beacons via POST message - **TestEventLoop_ApiUpdate_DELETE**: Tests removing beacons via DELETE message - **TestEventLoop_ApiUpdate_DELETE_All**: Tests clearing all beacons - **TestEventLoop_AlertMessage**: Tests alert message handling and MQTT publishing - **TestEventLoop_TrackerMessage**: Tests tracker message handling and MQTT publishing - **TestEventLoop_ContextCancellation**: Tests graceful shutdown on context cancellation ### 3. Integration Tests (`integration_test.go`) End-to-end tests that interact with real Kafka infrastructure: - **TestIntegration_EndToEnd**: Tests complete flow from MQTT message to Kafka - **TestIntegration_MultipleMessages**: Tests handling multiple sequential messages - **TestIntegration_AppStateConcurrency**: Tests concurrent access to AppState - **TestIntegration_CleanLookup**: Tests the CleanLookup functionality ## Running Tests ### Run All Tests ```bash go test ./tests/bridge/... ``` ### Run Only Unit Tests (skip integration tests) ```bash go test ./tests/bridge/... -short ``` ### Run with Verbose Output ```bash go test ./tests/bridge/... -v ``` ### Run Specific Test ```bash go test ./tests/bridge/... -run TestMQTTHandler_SingleReading ``` ### Run with Coverage ```bash go test ./tests/bridge/... -cover ``` ### Generate Coverage Report ```bash go test ./tests/bridge/... -coverprofile=coverage.out go tool cover -html=coverage.out ``` ## Integration Test Prerequisites Integration tests require a running Kafka instance. By default, they connect to `localhost:9092`. ### Running Kafka with Docker ```bash docker run -d \ --name kafka-test \ -p 9092:9092 \ -e KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 \ -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092 \ -e KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1 \ confluentinc/cp-kafka:latest ``` ### Custom Kafka URL Set the `KAFKA_URL` environment variable: ```bash KAFKA_URL=your-kafka-broker:9092 go test ./tests/bridge/... ``` ## Test Utilities The `testutil.go` file provides helper functions: - `NewTestHelper(t)`: Creates a test helper instance - `CreateRawReading(mac, rssi)`: Creates test beacon readings - `GenerateTestMAC(index)`: Generates test MAC addresses - `SetupTestBeacons(appState)`: Sets up standard test beacons - `AssertKafkaMessageCount(t, writer, expected)`: Asserts Kafka message count ## Mocks ### MockKafkaWriter A mock implementation of the Kafka writer for unit tests that captures all messages written to it: ```go mockWriter := &MockKafkaWriter{Messages: []kafka.Message{}} // ... use in tests ... if len(mockWriter.Messages) != expected { t.Errorf("Expected %d messages, got %d", expected, len(mockWriter.Messages)) } ``` ### MockMQTTClient A mock implementation of the MQTT client for testing event loop logic: ```go mockClient := NewMockMQTTClient() // ... use in tests ... if _, exists := mockClient.PublishedMessages["/alerts"]; !exists { t.Error("Expected message to be published to /alerts topic") } ``` ## Key Test Scenarios ### Beacon Lookup Flow 1. Beacon is added to lookup via POST message 2. MQTT message arrives with beacon reading 3. Handler checks if beacon exists in lookup 4. If exists, reading is forwarded to Kafka 5. If not, reading is skipped ### Message Filtering - Gateway-type readings are filtered out - Unknown beacons (not in lookup) are skipped - Invalid JSON is logged and ignored ### Concurrent Access - Multiple goroutines can safely access AppState - Beacon additions/removals are thread-safe - CleanLookup removes all entries atomically ## Troubleshooting ### Integration Tests Fail 1. Ensure Kafka is running: `docker ps | grep kafka` 2. Check Kafka logs: `docker logs kafka-test` 3. Verify connectivity: `telnet localhost 9092` 4. Check topic creation permissions ### Tests Time Out - Increase timeout in test context - Check Kafka broker responsiveness - Verify network connectivity ### Import Errors - Ensure you're in the project root directory - Check that go.mod is up to date: `go mod tidy` - Verify module path is correct ## Contributing When adding new tests: 1. Follow the existing naming convention: `Test_` 2. Use table-driven tests for multiple similar cases 3. Add comments explaining what is being tested 4. Use test utilities where appropriate 5. Ensure tests are independent and can run in parallel ## Notes - Unit tests mock all external dependencies (Kafka, MQTT) - Integration tests require real Kafka but mock MQTT - All tests clean up after themselves - Tests can run in parallel (no shared state) - Context cancellation is properly tested for graceful shutdown