11defmodule Supavisor.Integration.PostgresSwitchingTest do
22 use SupavisorWeb.ConnCase , async: false
3+ use Supavisor.PostgresCase , async: false
34
4- alias Supavisor.Jwt.Token
5+ import Supavisor.Support.Tenants
56
67 @ moduletag integration_docker: true
78
@@ -13,7 +14,8 @@ defmodule Supavisor.Integration.PostgresSwitchingTest do
1314 @ db_host "localhost"
1415
1516 setup % { conn: conn } do
16- cleanup_containers ( )
17+ containers = [ container_name ( 15 ) , container_name ( 16 ) ]
18+ cleanup_containers ( containers )
1719
1820 jwt = gen_token ( )
1921
@@ -22,17 +24,19 @@ defmodule Supavisor.Integration.PostgresSwitchingTest do
2224 |> put_req_header ( "accept" , "application/json" )
2325 |> put_req_header ( "authorization" , "Bearer " <> jwt )
2426
25- on_exit ( fn -> cleanup_containers ( ) end )
27+ on_exit ( fn -> cleanup_containers ( containers ) end )
2628
2729 { :ok , conn: conn }
2830 end
2931
3032 test "PostgreSQL upgrade scenario: 15 -> 16" , % { conn: conn } do
31- start_postgres_container ( 15 )
32- create_tenant ( conn )
33- assert :ok = test_connection ( )
33+ opts = build_opts ( 15 , @ tenant_name )
3434
35- stop_postgres_container ( 15 )
35+ start_postgres_container ( opts )
36+ create_tenant ( conn , opts )
37+ assert :ok = test_connection ( opts )
38+
39+ stop_postgres_container ( opts [ :container_name ] )
3640
3741 # Ideally, we shouldn't need to terminate the tenant manually here.
3842 #
@@ -43,139 +47,41 @@ defmodule Supavisor.Integration.PostgresSwitchingTest do
4347 #
4448 # Currently, if we don't terminate the tenant (or restart supavisor),
4549 # we get authentication errors.
46- terminate_tenant ( conn )
50+ terminate_tenant ( conn , @ tenant_name )
4751 Process . sleep ( 2000 )
48- start_postgres_container ( 16 )
49-
50- assert :ok = test_connection ( )
51- end
52-
53- defp start_postgres_container ( version ) do
54- container_name = container_name ( version )
55-
56- { _output , 0 } =
57- System . cmd ( "docker" , [
58- "run" ,
59- "-d" ,
60- "--name" ,
61- container_name ,
62- "-e" ,
63- "POSTGRES_USER=#{ @ postgres_user } " ,
64- "-e" ,
65- "POSTGRES_PASSWORD=#{ @ postgres_password } " ,
66- "-e" ,
67- "POSTGRES_DB=#{ @ postgres_db } " ,
68- "-p" ,
69- "#{ @ postgres_port } :5432" ,
70- "postgres:#{ version } "
71- ] )
72-
73- wait_for_postgres ( )
74- end
75-
76- defp wait_for_postgres ( max_attempts \\ 30 ) do
77- wait_for_postgres ( 1 , max_attempts )
78- end
79-
80- defp wait_for_postgres ( attempt , max_attempts ) when attempt != max_attempts do
81- case System . cmd ( "pg_isready" , [
82- "-h" ,
83- "localhost" ,
84- "-p" ,
85- to_string ( @ postgres_port ) ,
86- "-U" ,
87- @ postgres_user ,
88- "-d" ,
89- @ postgres_db
90- ] ) do
91- { _ , 0 } ->
92- :ok
93-
94- _ ->
95- Process . sleep ( 1000 )
96- wait_for_postgres ( attempt + 1 , max_attempts )
97- end
98- end
9952
100- defp wait_for_postgres ( _attempt , max_attempts ) do
101- raise "PostgreSQL failed to start within #{ max_attempts } seconds"
102- end
53+ opts = build_opts ( 16 , @ tenant_name )
54+ start_postgres_container ( opts )
10355
104- defp stop_postgres_container ( version ) do
105- System . cmd ( "docker" , [ "stop" , container_name ( version ) ] )
106- System . cmd ( "docker" , [ "rm" , container_name ( version ) ] )
56+ assert :ok = test_connection ( opts )
10757 end
10858
109- defp create_tenant ( conn ) do
110- tenant_attrs = % {
111- db_host: @ db_host ,
112- db_port: @ postgres_port ,
113- db_database: @ postgres_db ,
114- external_id: @ tenant_name ,
115- ip_version: "auto" ,
116- enforce_ssl: false ,
117- require_user: false ,
118- auth_query: "SELECT rolname, rolpassword FROM pg_authid WHERE rolname=$1;" ,
119- users: [
120- % {
121- db_user: @ postgres_user ,
122- db_password: @ postgres_password ,
123- pool_size: 20 ,
124- mode_type: "transaction" ,
125- is_manager: true
126- }
127- ]
128- }
129-
130- conn = put ( conn , Routes . tenant_path ( conn , :update , @ tenant_name ) , tenant: tenant_attrs )
131-
132- case conn . status do
133- status when status in 200 .. 201 ->
134- :ok
135-
136- _status ->
137- :ok
138- end
59+ defp build_opts ( version , external_id ) do
60+ Keyword . merge ( postgres_container_opts ( version ) ,
61+ container_name: container_name ( version ) ,
62+ external_id: external_id
63+ )
13964 end
14065
141- defp terminate_tenant ( conn ) do
142- _conn = get ( conn , Routes . tenant_path ( conn , :terminate , @ tenant_name ) )
143- :ok
144- end
145-
146- defp test_connection do
147- proxy_port = Application . fetch_env! ( :supavisor , :proxy_port_transaction )
148-
149- connection_opts = [
150- hostname: @ db_host ,
151- port: proxy_port ,
152- database: @ postgres_db ,
153- username: "#{ @ postgres_user } .#{ @ tenant_name } " ,
66+ defp postgres_container_opts ( version ) do
67+ [
68+ image: "postgres:#{ version } " ,
69+ port: @ postgres_port ,
70+ user: @ postgres_user ,
15471 password: @ postgres_password ,
155- # This is important as otherwise Postgrex may try to reconnect in case of errors.
156- # We want to avoid that, as it hides connection errors.
157- backoff: nil
72+ database: @ postgres_db ,
73+ hostname: @ db_host
15874 ]
75+ end
76+
77+ defp test_connection ( opts ) do
78+ connection_opts = connection_opts ( opts )
15979
16080 assert { :ok , conn } = Postgrex . start_link ( connection_opts )
16181 assert { :ok , % { rows: [ [ _version_string ] ] } } = Postgrex . query ( conn , "SELECT version();" , [ ] )
16282
16383 :ok
16484 end
16585
166- defp container_name ( version ) do
167- "test_postgres_#{ version } _switching"
168- end
169-
170- defp cleanup_containers do
171- [ 15 , 16 ]
172- |> Enum . each ( fn version ->
173- System . cmd ( "docker" , [ "rm" , "-f" , container_name ( version ) ] , stderr_to_stdout: true )
174- end )
175- end
176-
177- defp gen_token do
178- secret = Application . fetch_env! ( :supavisor , :api_jwt_secret )
179- Token . gen! ( secret )
180- end
86+ defp container_name ( version ) , do: "test_postgres_#{ version } _switching"
18187end
0 commit comments