@@ -5,6 +5,12 @@ defmodule RemotePersistentTerm.Fetcher.S3Test do
55 setup :verify_on_exit!
66 import ExUnit.CaptureLog
77
8+ @ bucket "test-bucket"
9+ @ key "test-key"
10+ @ region "test-region"
11+ @ failover_region "failover-region"
12+ @ version "F76V.weh4uOlU15f7a2OLHPgCLXkDpm4"
13+
814 test "Unknown error returns an error for current_version/1" do
915 expect ( AwsClientMock , :request , fn _op , _opts ->
1016 { :error , :unknown_error }
@@ -26,4 +32,101 @@ defmodule RemotePersistentTerm.Fetcher.S3Test do
2632 S3 . init ( bucket: bucket , key: key , region: region )
2733 end
2834 end
35+
36+ describe "failover_region" do
37+ test "current_identifiers/1 tries failover region when primary region fails" do
38+ # Setup state with failover region
39+ state = % S3 {
40+ bucket: @ bucket ,
41+ key: @ key ,
42+ region: @ region ,
43+ failover_region: @ failover_region
44+ }
45+
46+ # Mock the AWS client to fail for primary region but succeed for failover region
47+ expect ( AwsClientMock , :request , 2 , fn _op , opts ->
48+ case opts do
49+ [ region: @ region ] ->
50+ { :error , "Primary region connection error" }
51+
52+ [ region: @ failover_region ] ->
53+ { :ok ,
54+ % {
55+ body: % {
56+ versions: [
57+ % { version_id: @ version , etag: "current-etag" , is_latest: "true" }
58+ ]
59+ }
60+ } }
61+ end
62+ end )
63+
64+ log =
65+ capture_log ( fn ->
66+ result = S3 . current_version ( state )
67+ assert { :ok , "current-etag" } = result
68+ end )
69+
70+ assert log =~ "Failed to fetch from primary region #{ @ region } "
71+ assert log =~ "will try failover region #{ @ failover_region } "
72+ end
73+
74+ test "download/1 tries failover region when primary region fails" do
75+ state = % S3 {
76+ bucket: @ bucket ,
77+ key: @ key ,
78+ region: @ region ,
79+ failover_region: @ failover_region
80+ }
81+
82+ # Mock the AWS client to fail for primary region but succeed for failover region
83+ expect ( AwsClientMock , :request , 2 , fn _op , opts ->
84+ case opts do
85+ [ region: @ region ] ->
86+ { :error , "Primary region connection error" }
87+
88+ [ region: @ failover_region ] ->
89+ { :ok , % { body: "content from failover region" } }
90+ end
91+ end )
92+
93+ log =
94+ capture_log ( fn ->
95+ result = S3 . download ( state )
96+ assert { :ok , "content from failover region" } = result
97+ end )
98+
99+ assert log =~ "Failed to fetch from primary region #{ @ region } "
100+ assert log =~ "will try failover region #{ @ failover_region } "
101+ end
102+
103+ test "returns error when both primary and failover regions fail" do
104+ state = % S3 {
105+ bucket: @ bucket ,
106+ key: @ key ,
107+ region: @ region ,
108+ failover_region: @ failover_region
109+ }
110+
111+ # Mock the AWS client to fail for both regions
112+ expect ( AwsClientMock , :request , 2 , fn _op , opts ->
113+ case opts do
114+ [ region: @ region ] ->
115+ { :error , "Primary region connection error" }
116+
117+ [ region: @ failover_region ] ->
118+ { :error , "Failover region connection error" }
119+ end
120+ end )
121+
122+ log =
123+ capture_log ( fn ->
124+ result = S3 . download ( state )
125+ assert { :error , _ } = result
126+ end )
127+
128+ assert log =~ "Failed to fetch from primary region #{ @ region } "
129+ assert log =~ "will try failover region #{ @ failover_region } "
130+ end
131+ end
29132end
0 commit comments