Changelog

All notable changes to Macavity are documented in this file.

0.2.0

This release replaces the single armed fault with a per-session event registry. A session can now arm multiple fault events at once. Each event has a stable ID, independent counters, a lifecycle state, and can be re-armed after firing.

Breaking changes. The return types and behavior of macavity_arm(), macavity_disarm() and macavity_status() have changed. See Upgrading from 0.1.0.

Added

  • Event registry. Events are kept in a backend-local registry until macavity_reset() is called or the session ends. The registry also serves as the session’s event history. Event IDs are allocated as 1, 2, 3, … in creation order and are never reused until reset.
  • Multiple armed events. Any number of events can be armed simultaneously, at the same or different fault points. Each event maintains its own counters.
  • Event states. Each event is armed, completed (it fired), or disarmed (it was cancelled before firing).
  • Deterministic firing order. When multiple armed events match the same hit, they are evaluated by action in the order delay > crash > error, then by ascending event_id. A delay returns and evaluation continues; an error or crash ends evaluation, so later events are neither counted nor fired.
  • macavity_arm(event_id integer) RETURNS boolean re-arms a completed or disarmed event. The event keeps its ID, point, action and occurrence, while its counters are reset. It returns false if the event is already armed. An unknown or NULL ID is an error.
  • Action-specific shorthands: macavity_arm_error(point, occurrence), macavity_arm_delay(point, occurrence) and macavity_arm_crash(point, occurrence). Each returns the new event’s ID.
  • macavity_reset() RETURNS integer clears the registry, restarts event IDs at 1, and returns the number of discarded events.
  • Added the macavity_events regression suite covering event IDs, concurrent events, state transitions, status output and firing precedence.
  • Extended session and crash tests to cover multiple concurrent sessions and firing precedence under real crashes.
  • Added sql/macavity--0.1.0--0.2.0.sql for ALTER EXTENSION macavity UPDATE.

Changed

  • Breaking: macavity_arm(point, action, occurrence) now returns the new event’s integer ID instead of void.
  • Breaking: macavity_disarm(event_id integer DEFAULT NULL) RETURNS boolean now:

    • disarms the specified event when given an ID;
    • disarms all armed events when called with no argument or NULL;
    • returns true if at least one event changed state;
    • preserves disarmed and completed events in the registry. Use macavity_reset() to clear them.
  • Breaking: macavity_status() now returns one row per event (SETOF record) with the columns event_id, point, action, occurrence, hits, remaining and state.

    • The state column replaces the boolean armed column.
    • A session with no events now returns no rows.
  • Arming a new event while another is armed is no longer an error.
  • The arming-statement skip now applies to each event separately. The statement that arms or re-arms an event does not count toward that event’s own executor_end, before_commit or before_abort hits.
  • On Windows builds, macavity_arm() and macavity_arm_crash() reject the crash action with feature_not_supported.
  • macavity_points() remains granted to PUBLIC. All new functions are revoked from PUBLIC, like the existing arming functions.
  • Restructured the README with new “Overview”, “Usage”, “SQL API” and “How events behave” sections.

Fixed

  • Fixed an executor_end event firing one statement late when the statement that armed it failed. The per-statement skip is now discarded when execution unwinds due to an error, with a transaction-end backstop.

Upgrading from 0.1.0

  1. Build and install the new version: make && make install
  2. Run ALTER EXTENSION macavity UPDATE; in each database that has the extension. The upgrade drops and recreates macavity_arm(), macavity_disarm() and macavity_status() because their return types changed.
  3. Re-issue any GRANTs you had on those functions. The upgrade revokes the new and recreated functions from PUBLIC.
  4. Update callers:

    • Replace checks on armed with checks on state, for example WHERE state = 'armed'.
    • Where you relied on macavity_disarm() to clear fired state, use macavity_reset() instead.
    • Code that expected one row from macavity_status() must now handle zero or multiple rows.
  5. Existing sessions keep the old library loaded until they reconnect. No fault state is carried across the upgrade because fault state has always lived in backend memory.

0.1.0

Initial release.

  • Session-local, one-shot fault injection, with at most one armed fault per session.
  • Four fault points: executor_start, executor_end, before_commit and before_abort.
  • Three actions: error, delay (fixed at 1 second) and crash (the backend sends SIGKILL to itself).
  • macavity_arm(), macavity_disarm(), macavity_status() and macavity_points(). The hits and remaining counters are updated before the action runs.
  • The pg_regress suites macavity_basic, macavity_errors, macavity_counters and macavity_faults, plus test/session_test.sh and test/crash_test.sh.