@@ -102,13 +102,16 @@ defmodule BitcrowdEcto.RepoTest do
102102 assert TestRepo . fetch_by ( query , [ ] ) == { :ok , resource }
103103 end
104104
105- # The actual lock is non-trivial to test, I tried.
106105 test "can lock for :update" , % { resource: % { id: id } = resource } do
107- assert TestRepo . fetch_by ( TestSchema , [ id: id ] , lock: :update ) == { :ok , resource }
106+ assert_lock_granted ( "relation = 'test_schema_pkey'::regclass::oid" , fn ->
107+ assert TestRepo . fetch_by ( TestSchema , [ id: id ] , lock: :update ) == { :ok , resource }
108+ end )
108109 end
109110
110111 test "can lock for :no_key_update" , % { resource: % { id: id } = resource } do
111- assert TestRepo . fetch_by ( TestSchema , [ id: id ] , lock: :no_key_update ) == { :ok , resource }
112+ assert_lock_granted ( "relation = 'test_schema_pkey'::regclass::oid" , fn ->
113+ assert TestRepo . fetch_by ( TestSchema , [ id: id ] , lock: :no_key_update ) == { :ok , resource }
114+ end )
112115 end
113116
114117 test "converts CastErrors for binary_id columns to not_found errors" do
@@ -161,4 +164,41 @@ defmodule BitcrowdEcto.RepoTest do
161164 assert TestRepo . fetch_by ( TestSchema , [ id: resource . id ] , prefix: prefix ) == { :ok , resource }
162165 end
163166 end
167+
168+ describe "advisory_xact_lock/1" do
169+ test "acquires an advisory lock" do
170+ assert_lock_granted ( "locktype = 'advisory'" , fn ->
171+ TestRepo . advisory_xact_lock ( "foo" )
172+ end )
173+ end
174+
175+ test "accepts atoms" do
176+ assert_lock_granted ( "locktype = 'advisory'" , fn ->
177+ TestRepo . advisory_xact_lock ( :foo )
178+ end )
179+ end
180+ end
181+
182+ defp assert_lock_granted ( where , fun ) do
183+ assert locks_granted ( where ) == 0
184+ result = fun . ( )
185+ assert locks_granted ( where ) == 1
186+ result
187+ end
188+
189+ defp locks_granted ( where ) do
190+ % { rows: [ [ vxid ] ] } =
191+ TestRepo . query! ( """
192+ SELECT virtualtransaction FROM pg_locks
193+ WHERE transactionid::text = (txid_current() % (2^32)::bigint)::text;
194+ """ )
195+
196+ % { rows: [ [ count ] ] } =
197+ TestRepo . query! ( """
198+ SELECT COUNT(*) FROM pg_locks
199+ WHERE virtualtransaction = '#{ vxid } ' AND granted IS TRUE AND #{ where } ;
200+ """ )
201+
202+ count
203+ end
164204end
0 commit comments