aprs.me/test/support/data_case.ex
Graham McIntire b5a39102a6
fix: Comprehensive packet processing and test optimization improvements
This commit includes several critical fixes and optimizations:

## Production Buffer Overflow Fix
- Fixed telemetry_vals data type conversion from strings to integers
- Enhanced put_telemetry_fields() with robust type conversion logic
- Handles mixed data types (string, integer, float) gracefully
- Prevents PacketConsumer GenServer crashes that caused buffer overflow
- Processes telemetry from both data_extended and top-level attrs

## Test Suite Performance Optimization
- Improved test execution speed by 48% (43.2s → 24.1s)
- Increased parallelization: max_cases from 16 to 48
- Optimized database connections and reduced timeouts
- Tagged slow tests and exclude them by default for fast development
- Fixed device seeding to only run when needed
- Enhanced log capture for packet consumer tests

## Code Quality Improvements
- Fixed handle_info clause grouping in LeaderElection
- Ensures mix compile --warnings-as-errors passes
- Added comprehensive telemetry conversion tests
- Improved test reliability and reduced flakiness

## Infrastructure Updates
- Added migration init container to StatefulSet for automatic schema updates
- Disabled AUTO_MIGRATE in main container (handled by init container)
- Created .test-commands with helpful test aliases

This resolves production stability issues and significantly improves development workflow.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-01 17:50:07 -05:00

82 lines
2.3 KiB
Elixir

defmodule Aprsme.DataCase do
@moduledoc """
This module defines the test case to be used by
data tests.
You may define functions here to be used as helpers in
your data tests. See `errors_on/2`'s definition as an example.
Finally, if the test case interacts with the database,
we enable the SQL sandbox, so changes done to the database
are reverted at the end of every test. If you use PostgreSQL, you
can even run database tests asynchronously by setting
`use Aprsme.DataCase, async: true`, although
this option is not recommended for other databases.
"""
use ExUnit.CaseTemplate
alias Ecto.Adapters.SQL.Sandbox
using do
quote do
import Aprsme.DataCase
# Import conveniences for testing with connections
import Ecto
import Ecto.Changeset
import Ecto.Query
# and other functionality to make calls such as:
# import Aprsme.DataCase
# Aprsme.DataCase.errors_on(MySchema.changeset(%MySchema{}, %{}))
# The default import for Repo
alias Aprsme.Repo
end
end
setup tags do
Aprsme.DataCase.setup_sandbox(tags)
# Only seed devices for tests that need them
if tags[:needs_devices] do
Aprsme.DevicesSeeder.seed_from_json()
end
:ok
end
@doc """
A helper that transforms changeset errors into a map of messages.
iex> errors_on(MySchema.changeset(%MySchema{}, %{field: bad_value}))
%{field: ["has invalid value"]}
"""
def errors_on(changeset) do
Ecto.Changeset.traverse_errors(changeset, &translate_error/1)
end
@doc """
Sets up the sandbox and allows the test case
to be run asynchronously.
"""
def setup_sandbox(tags) do
pid = Sandbox.start_owner!(Aprsme.Repo, shared: not tags[:async])
on_exit(fn -> Sandbox.stop_owner(pid) end)
end
defp translate_error({msg, opts}) do
# You can make use of gettext to translate error messages by
# uncommenting and adjusting the following code:
# if count = opts[:count] do
# Gettext.dngettext(AprsmeWeb.Gettext, "errors", msg, msg, count, opts)
# else
# Gettext.dgettext(AprsmeWeb.Gettext, "errors", msg, opts)
# end
Enum.reduce(opts, msg, fn {key, value}, acc ->
String.replace(acc, "%{#{key}}", fn _ -> to_string(value) end)
end)
end
end