#!/usr/bin/env elixir Mix.install([]) defmodule IntegrationHeaderTest do @moduledoc """ Integration test for header processing in the enhanced protocol. """ def run do IO.puts("šŸ”¬ Header Integration Test") IO.puts("=" |> String.duplicate(40)) test_header_extraction() test_header_response() test_no_header_config() test_header_mismatch() IO.puts("\nāœ… Integration tests completed!") end defp test_header_extraction do IO.puts("\nšŸ“‹ Test 1: Header Extraction") # Simulate incoming data with header: 6000782000 + ISO message header_data = <<0x60, 0x00, 0x78, 0x20, 0x00>> iso_message = <<0x08, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00>> full_data = header_data <> iso_message # Channel config with header enabled channel_config = %{ channel_id: "channel_001", port: 8583, header: %{ enabled: true, type: :base1, encoding: :hex, pattern: "6000782000", length: 5 } } IO.puts(" Full data: #{Base.encode16(full_data)}") IO.puts(" Expected header: #{Base.encode16(header_data)}") IO.puts(" Expected ISO: #{Base.encode16(iso_message)}") # Simulate header extraction process case extract_header_from_config(channel_config, full_data) do {:ok, extracted_header, remaining_data} -> IO.puts(" āœ… Header extracted successfully") IO.puts(" Extracted: #{Base.encode16(extracted_header)}") IO.puts(" Remaining: #{Base.encode16(remaining_data)}") if extracted_header == header_data and remaining_data == iso_message do IO.puts(" āœ… Data matches expected values") else IO.puts(" āŒ Data doesn't match expected values") end {:error, reason} -> IO.puts(" āŒ Header extraction failed: #{reason}") end end defp test_header_response do IO.puts("\nšŸ“¤ Test 2: Header Response Generation") # Simulate response generation iso_response = <<0x08, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00>> original_header = <<0x60, 0x00, 0x78, 0x20, 0x00>> channel_config = %{ header: %{ enabled: true, type: :base1, encoding: :hex, pattern: "6000782000", length: 5 } } case add_header_to_response(channel_config, original_header, iso_response) do {:ok, full_response} -> expected_length = 5 + 10 # header + ISO response if byte_size(full_response) == expected_length do IO.puts(" āœ… Response with header generated correctly") IO.puts(" Response: #{Base.encode16(full_response)}") else IO.puts(" āŒ Response length incorrect: #{byte_size(full_response)} vs #{expected_length}") end {:error, reason} -> IO.puts(" āŒ Response generation failed: #{reason}") end end defp test_no_header_config do IO.puts("\n🚫 Test 3: No Header Configuration") iso_data = <<0x08, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00>> channel_config = %{ channel_id: "channel_002", port: 5000, header: %{enabled: false} } case extract_header_from_config(channel_config, iso_data) do {:ok, nil, remaining_data} -> if remaining_data == iso_data do IO.puts(" āœ… No header processing - data passed through") else IO.puts(" āŒ Data was modified when it shouldn't be") end other -> IO.puts(" āŒ Unexpected result: #{inspect(other)}") end end defp test_header_mismatch do IO.puts("\nāŒ Test 4: Header Mismatch") # Wrong header in the data wrong_header = <<0x70, 0x00, 0x78, 0x20, 0x00>> iso_message = <<0x08, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00>> full_data = wrong_header <> iso_message channel_config = %{ header: %{ enabled: true, type: :base1, encoding: :hex, pattern: "6000782000", # Expects different header length: 5 } } case extract_header_from_config(channel_config, full_data) do {:error, :header_mismatch} -> IO.puts(" āœ… Header mismatch correctly detected") {:error, other_reason} -> IO.puts(" āš ļø Different error detected: #{other_reason}") {:ok, _, _} -> IO.puts(" āŒ Header mismatch should have been detected") end end # Helper functions that simulate the actual header processing logic defp extract_header_from_config(%{header: %{enabled: false}}, data) do {:ok, nil, data} end defp extract_header_from_config(%{header: header_config}, data) when header_config.enabled do # Convert pattern to binary case hex_to_binary(header_config.pattern) do {:ok, pattern_binary} -> pattern_size = byte_size(pattern_binary) if byte_size(data) >= pattern_size do <> = data if header_part == pattern_binary do {:ok, header_part, remaining} else {:error, :header_mismatch} end else {:error, :insufficient_data} end {:error, reason} -> {:error, reason} end end defp add_header_to_response(%{header: %{enabled: false}}, _original_header, iso_response) do {:ok, iso_response} end defp add_header_to_response(%{header: header_config}, original_header, iso_response) when header_config.enabled do {:ok, original_header <> iso_response} end defp hex_to_binary(hex_string) when is_binary(hex_string) do if String.match?(hex_string, ~r/^[0-9A-Fa-f]+$/) do padded_hex = if rem(String.length(hex_string), 2) == 1 do "0" <> hex_string else hex_string end case Base.decode16(padded_hex, case: :mixed) do {:ok, binary} -> {:ok, binary} :error -> {:error, :invalid_hex} end else {:error, :invalid_hex} end end end IntegrationHeaderTest.run()