NAME
DBIO::Test::ExtensionSet - Commutativity test for a set of database extension classes (ADR 0066)
VERSION
version 0.900004
SYNOPSIS
In the test of a driver, or of an extension distribution:
use DBIO::Test::ExtensionSet qw(extension_set_ok);
extension_set_ok(
driver => 'DBIO::PostgreSQL::Deploy',
extensions => [
'DBIO::PostgreSQL::Age::Extension',
'DBIO::PostgreSQL::PostGIS::Extension',
],
source => $live_model,
target => $target_model,
dbh => $fake_dbh,
changes => [ { kind => 'column_type', table => ..., column_name => ..., old_info => {...}, new_info => {...} } ],
name => 'AGE and PostGIS commute',
);
DESCRIPTION
The protocol of DBIO::Extension::Protocol hands every extension of a phase the same input and merges the answers by unions with a refusal on conflict, so the result does not depend on the order. It cannot ensure that an extension stays inside the protocol: one that changes its input, keeps state between calls, or answers differently depending on what ran before breaks the property (ADR 0066 section 2.4, rule 6 of "WRITING AN EXTENSION" in DBIO::Extension). This module checks exactly that.
Given a driver (a DBIO::Deploy::Base subclass: it applies claims and annotations to the model and may supply the diff class), a set of extension classes and an offline fixture -- a source and a target model, a stand-in for the database handle that the extensions' inspect reads, and optionally changes to ask verdict about -- it runs the phases in every permutation of the set (all permutations up to five extensions; above, every rotation of the name order and of its reverse), overriding the name order only here, and runs each order twice. It asserts
the same post-phase source and target model,
the same diff statements, the same verdicts and refusals,
the same activation and the same
inspectstates,per extension the same output of every phase in every position and in the repeated run (an extension with state between calls differs from itself),
that every extension got a copy of its input and the copy came back unchanged (the input and the context).
An exception from the protocol (an annotate conflict, a malformed answer, a driver that cannot apply what the set claims, a wrong interface version) is a violation as well: a set that cannot run does not commute.
A driver runs it over the extensions of its family; an extension distribution runs it over itself and every extension it names as a peer.
METHODS
extension_set_orders
my @orders = extension_set_orders(@names);
The orders the test runs, each an array reference of names. All permutations for up to five names; above that every rotation of @names and of its reverse (duplicates removed).
extension_set_violations
my @violations = extension_set_violations(%args);
Runs the test and returns the violations as strings; empty when the set commutes. Arguments:
driver-
A class name or object of a DBIO::Deploy::Base subclass. A class name is loaded by the test; a class that cannot be loaded throws a DBIO::Exception naming it. The class needs no schema for the hooks the protocol uses (
_apply_extension_claims,_apply_extension_annotations,_apply_extension_states,_extension_driver_helpers,_extension_connection_schema,_extension_restricted,_diff_class). It is built with->newwithout arguments. Required. extensions-
An array reference of extension classes, or of entries
{ class, name, options, installed, version, schema }. The name is the class'snameunless the entry gives one. An entry without installed state counts as installed;installed(below) overrides. installed-
Optional: name to
{ installed, version, schema }. source,target-
The offline fixture: the source (live) model and the target model, in the driver's shape. Required. They are copied; the test never changes them.
dbh-
What
$ctx->{dbh}is ininspect: a hash or fake object the extensions read. Optional. changes-
Optional: array reference of changes to ask
verdictabout, in the driver's form. diff-
Optional code reference
($source, $target, $protocol)returning the diff statements as an array reference, for a driver whose diff is not a plain_diff_class->new(source =>, target =>, extensions =>)->as_sql. Default: that.
extension_set_ok
extension_set_ok(%args, name => 'the set commutes');
"extension_set_violations" as a test: one ok that fails with the violations as diagnostics. Returns the result of the test. builder may name a Test::Builder to report to (default: the one of Test::More).
AUTHOR
DBIO & DBIx::Class Authors
COPYRIGHT AND LICENSE
Copyright (C) 2026 DBIO Authors Portions Copyright (C) 2005-2025 DBIx::Class Authors Based on DBIx::Class, heavily modified.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.