/** * MessageTest - Unit tests for Protocol messages */ using Implexus.Core; using Implexus.Protocol; using Implexus.Storage; public static int main(string[] args) { int passed = 0; int failed = 0; // Test 1: Message header serialization if (test_message_header()) { passed++; stdout.puts("PASS: test_message_header\n"); } else { failed++; stdout.puts("FAIL: test_message_header\n"); } // Test 2: GetEntityRequest if (test_get_entity_request()) { passed++; stdout.puts("PASS: test_get_entity_request\n"); } else { failed++; stdout.puts("FAIL: test_get_entity_request\n"); } // Test 3: EntityExistsRequest if (test_entity_exists_request()) { passed++; stdout.puts("PASS: test_entity_exists_request\n"); } else { failed++; stdout.puts("FAIL: test_entity_exists_request\n"); } // Test 4: CreateContainerRequest if (test_create_container_request()) { passed++; stdout.puts("PASS: test_create_container_request\n"); } else { failed++; stdout.puts("FAIL: test_create_container_request\n"); } // Test 5: CreateDocumentRequest if (test_create_document_request()) { passed++; stdout.puts("PASS: test_create_document_request\n"); } else { failed++; stdout.puts("FAIL: test_create_document_request\n"); } // Test 6: DeleteEntityRequest if (test_delete_entity_request()) { passed++; stdout.puts("PASS: test_delete_entity_request\n"); } else { failed++; stdout.puts("FAIL: test_delete_entity_request\n"); } // Test 7: SetPropertyRequest if (test_set_property_request()) { passed++; stdout.puts("PASS: test_set_property_request\n"); } else { failed++; stdout.puts("FAIL: test_set_property_request\n"); } // Test 8: GetPropertyRequest if (test_get_property_request()) { passed++; stdout.puts("PASS: test_get_property_request\n"); } else { failed++; stdout.puts("FAIL: test_get_property_request\n"); } // Test 9: EntityResponse if (test_entity_response()) { passed++; stdout.puts("PASS: test_entity_response\n"); } else { failed++; stdout.puts("FAIL: test_entity_response\n"); } // Test 10: BooleanResponse if (test_boolean_response()) { passed++; stdout.puts("PASS: test_boolean_response\n"); } else { failed++; stdout.puts("FAIL: test_boolean_response\n"); } // Test 11: PropertyResponse if (test_property_response()) { passed++; stdout.puts("PASS: test_property_response\n"); } else { failed++; stdout.puts("FAIL: test_property_response\n"); } // Test 12: ErrorResponse if (test_error_response()) { passed++; stdout.puts("PASS: test_error_response\n"); } else { failed++; stdout.puts("FAIL: test_error_response\n"); } // Test 13: SuccessResponse if (test_success_response()) { passed++; stdout.puts("PASS: test_success_response\n"); } else { failed++; stdout.puts("FAIL: test_success_response\n"); } // Test 14: MessageFactory if (test_message_factory()) { passed++; stdout.puts("PASS: test_message_factory\n"); } else { failed++; stdout.puts("FAIL: test_message_factory\n"); } // Test 15: Full message round-trip if (test_full_round_trip()) { passed++; stdout.puts("PASS: test_full_round_trip\n"); } else { failed++; stdout.puts("FAIL: test_full_round_trip\n"); } stdout.printf("\nResults: %d passed, %d failed\n", passed, failed); return failed > 0 ? 1 : 0; } // Test 1: Message header serialization bool test_message_header() { var header = new MessageHeader(); header.message_type = MessageType.GET_ENTITY; header.payload_length = 100; header.request_id = 42; var data = header.serialize(); if (data.length != HEADER_SIZE) return false; // Check magic bytes if (data[0] != 'I' || data[1] != 'M' || data[2] != 'P' || data[3] != 'X') return false; // Deserialize and verify try { var restored = MessageHeader.deserialize(data); if (restored.message_type != MessageType.GET_ENTITY) return false; if (restored.payload_length != 100) return false; if (restored.request_id != 42) return false; return true; } catch (ProtocolError e) { return false; } } // Test 2: GetEntityRequest bool test_get_entity_request() { try { var path = new EntityPath("/users/john"); var request = new GetEntityRequest.for_path(path); request.request_id = 1; var data = request.serialize(); // Deserialize header var header = MessageHeader.deserialize(data); if (header.message_type != MessageType.GET_ENTITY) return false; if (header.request_id != 1) return false; // Deserialize payload var restored = new GetEntityRequest(); restored.header = header; restored.deserialize_payload(data[HEADER_SIZE:data.length]); if (!restored.path.equals(path)) return false; return true; } catch (Error e) { return false; } } // Test 3: EntityExistsRequest bool test_entity_exists_request() { try { var path = new EntityPath("/test/path"); var request = new EntityExistsRequest.for_path(path); request.request_id = 2; var data = request.serialize(); var header = MessageHeader.deserialize(data); if (header.message_type != MessageType.ENTITY_EXISTS) return false; var restored = new EntityExistsRequest(); restored.header = header; restored.deserialize_payload(data[HEADER_SIZE:data.length]); if (!restored.path.equals(path)) return false; return true; } catch (Error e) { return false; } } // Test 4: CreateContainerRequest bool test_create_container_request() { try { var path = new EntityPath("/new_container"); var request = new CreateContainerRequest.for_path(path); request.request_id = 3; var data = request.serialize(); var header = MessageHeader.deserialize(data); if (header.message_type != MessageType.CREATE_CONTAINER) return false; var restored = new CreateContainerRequest(); restored.header = header; restored.deserialize_payload(data[HEADER_SIZE:data.length]); if (!restored.path.equals(path)) return false; return true; } catch (Error e) { return false; } } // Test 5: CreateDocumentRequest bool test_create_document_request() { try { var path = new EntityPath("/docs/new_doc"); var request = new CreateDocumentRequest.for_path_and_type(path, "Document"); request.request_id = 4; var data = request.serialize(); var header = MessageHeader.deserialize(data); if (header.message_type != MessageType.CREATE_DOCUMENT) return false; var restored = new CreateDocumentRequest(); restored.header = header; restored.deserialize_payload(data[HEADER_SIZE:data.length]); if (!restored.path.equals(path)) return false; if (restored.type_label != "Document") return false; return true; } catch (Error e) { return false; } } // Test 6: DeleteEntityRequest bool test_delete_entity_request() { try { var path = new EntityPath("/to_delete"); var request = new DeleteEntityRequest.for_path(path); request.request_id = 5; var data = request.serialize(); var header = MessageHeader.deserialize(data); if (header.message_type != MessageType.DELETE_ENTITY) return false; var restored = new DeleteEntityRequest(); restored.header = header; restored.deserialize_payload(data[HEADER_SIZE:data.length]); if (!restored.path.equals(path)) return false; return true; } catch (Error e) { return false; } } // Test 7: SetPropertyRequest bool test_set_property_request() { try { var path = new EntityPath("/entity"); var request = new SetPropertyRequest(); request.path = path; request.property_name = "test_prop"; request.value = new Invercargill.NativeElement("test_value"); request.request_id = 6; var data = request.serialize(); var header = MessageHeader.deserialize(data); if (header.message_type != MessageType.SET_PROPERTY) return false; var restored = new SetPropertyRequest(); restored.header = header; restored.deserialize_payload(data[HEADER_SIZE:data.length]); if (!restored.path.equals(path)) return false; if (restored.property_name != "test_prop") return false; // Check value if (restored.value == null || ((!) restored.value).is_null()) return false; string val = ((!) restored.value).as(); if (val != "test_value") return false; return true; } catch (Error e) { return false; } } // Test 8: GetPropertyRequest bool test_get_property_request() { try { var path = new EntityPath("/entity"); var request = new GetPropertyRequest(); request.path = path; request.property_name = "get_prop"; request.request_id = 7; var data = request.serialize(); var header = MessageHeader.deserialize(data); if (header.message_type != MessageType.GET_PROPERTY) return false; var restored = new GetPropertyRequest(); restored.header = header; restored.deserialize_payload(data[HEADER_SIZE:data.length]); if (!restored.path.equals(path)) return false; if (restored.property_name != "get_prop") return false; return true; } catch (Error e) { return false; } } // Test 9: EntityResponse bool test_entity_response() { try { var response = new EntityResponse(); response.entity_data.entity_type = EntityType.DOCUMENT; response.entity_data.path = new EntityPath("/test/document"); response.entity_data.type_label = "TestDoc"; response.request_id = 8; var data = response.serialize(); var header = MessageHeader.deserialize(data); if (header.message_type != MessageType.ENTITY_RESPONSE) return false; var restored = new EntityResponse(); restored.header = header; restored.deserialize_payload(data[HEADER_SIZE:data.length]); if (restored.entity_data.entity_type != EntityType.DOCUMENT) return false; if (!restored.entity_data.path.equals(new EntityPath("/test/document"))) return false; if (restored.entity_data.type_label != "TestDoc") return false; return true; } catch (Error e) { return false; } } // Test 10: BooleanResponse bool test_boolean_response() { try { // Test true var response_true = new BooleanResponse(); response_true.value = true; response_true.request_id = 9; var data_true = response_true.serialize(); var header_true = MessageHeader.deserialize(data_true); var restored_true = new BooleanResponse(); restored_true.header = header_true; restored_true.deserialize_payload(data_true[HEADER_SIZE:data_true.length]); if (restored_true.value != true) return false; // Test false var response_false = new BooleanResponse(); response_false.value = false; var data_false = response_false.serialize(); var header_false = MessageHeader.deserialize(data_false); var restored_false = new BooleanResponse(); restored_false.header = header_false; restored_false.deserialize_payload(data_false[HEADER_SIZE:data_false.length]); if (restored_false.value != false) return false; return true; } catch (Error e) { return false; } } // Test 11: PropertyResponse bool test_property_response() { try { var response = new PropertyResponse(); response.value = new Invercargill.NativeElement(12345); response.request_id = 10; var data = response.serialize(); var header = MessageHeader.deserialize(data); if (header.message_type != MessageType.PROPERTY_RESPONSE) return false; var restored = new PropertyResponse(); restored.header = header; restored.deserialize_payload(data[HEADER_SIZE:data.length]); if (restored.value == null || ((!) restored.value).is_null()) return false; int64? val = ((!) restored.value).as(); if (val == null || (!) val != 12345) return false; return true; } catch (Error e) { return false; } } // Test 12: ErrorResponse bool test_error_response() { try { var response = new ErrorResponse.with_error(404, "Entity not found"); response.request_id = 11; var data = response.serialize(); var header = MessageHeader.deserialize(data); if (header.message_type != MessageType.ERROR) return false; var restored = new ErrorResponse(); restored.header = header; restored.deserialize_payload(data[HEADER_SIZE:data.length]); if (restored.error_code != 404) return false; if (restored.error_message != "Entity not found") return false; return true; } catch (Error e) { return false; } } // Test 13: SuccessResponse bool test_success_response() { try { var response = new SuccessResponse(); response.request_id = 12; var data = response.serialize(); var header = MessageHeader.deserialize(data); if (header.message_type != MessageType.SUCCESS) return false; if (header.payload_length != 0) return false; var restored = new SuccessResponse(); restored.header = header; restored.deserialize_payload(data[HEADER_SIZE:data.length]); return true; } catch (Error e) { return false; } } // Test 14: MessageFactory bool test_message_factory() { try { // Test all message types var types = new MessageType[] { MessageType.GET_ENTITY, MessageType.ENTITY_EXISTS, MessageType.CREATE_CONTAINER, MessageType.CREATE_DOCUMENT, MessageType.DELETE_ENTITY, MessageType.SET_PROPERTY, MessageType.GET_PROPERTY, MessageType.GET_CHILDREN, MessageType.QUERY_BY_TYPE, MessageType.BEGIN_TRANSACTION, MessageType.COMMIT_TRANSACTION, MessageType.ROLLBACK_TRANSACTION, MessageType.ENTITY_RESPONSE, MessageType.BOOLEAN_RESPONSE, MessageType.PROPERTY_RESPONSE, MessageType.CHILDREN_RESPONSE, MessageType.QUERY_RESPONSE, MessageType.ERROR, MessageType.SUCCESS, MessageType.WELCOME }; foreach (var type in types) { var message = MessageFactory.create_message(type); if (message == null) return false; if (message.message_type != type) return false; } return true; } catch (Error e) { return false; } } // Test 15: Full message round-trip bool test_full_round_trip() { try { // Create a complex message var request = new CreateDocumentRequest.for_path_and_type( new EntityPath("/deeply/nested/path/document"), "ComplexDocument" ); request.request_id = 999; // Serialize var data = request.serialize(); // Parse header var header = MessageHeader.deserialize(data); // Create message from factory var restored = MessageFactory.create_message(header.message_type); if (restored == null) return false; ((!) restored).header = header; ((!) restored).deserialize_payload(data[HEADER_SIZE:data.length]); // Verify var doc_request = ((!) restored) as CreateDocumentRequest; if (doc_request == null) return false; if (((!) doc_request).path.to_string() != "/deeply/nested/path/document") return false; if (((!) doc_request).type_label != "ComplexDocument") return false; if (((!) doc_request).request_id != 999) return false; return true; } catch (Error e) { return false; } }