22
33import pretend
44
5- from warehouse .cli .search import reindex
5+ from opensearchpy .exceptions import NotFoundError
6+
7+ from warehouse .cli .search import delete_older_indices , print_indices , reindex
68from warehouse .search .tasks import reindex as _reindex
79
810
@@ -21,3 +23,183 @@ def test_reindex(self, cli):
2123 assert config .task .calls == [pretend .call (_reindex ), pretend .call (_reindex )]
2224 assert task .get_request .calls == [pretend .call ()]
2325 assert task .run .calls == [pretend .call (request )]
26+
27+ def test_print_indices (self , cli ):
28+ # Mock the OpenSearch client responses
29+ cat_client = pretend .stub (
30+ indices = pretend .call_recorder (
31+ lambda ** kw : "health status index id pri rep docs.count docs.deleted store.size creation.date.string\n green open production-2024-01-01 abc 1 0 1000 0 1mb 2024-01-01T00:00:00Z" # noqa: E501
32+ )
33+ )
34+ indices_client = pretend .stub (
35+ get_alias = pretend .call_recorder (
36+ lambda ** kw : {
37+ "production-2024-01-01" : {"aliases" : {"production" : {}}},
38+ "staging-2024-01-01" : {"aliases" : {"staging" : {}}},
39+ }
40+ )
41+ )
42+ client = pretend .stub (cat = cat_client , indices = indices_client )
43+ config = pretend .stub (registry = {"opensearch.client" : client })
44+
45+ result = cli .invoke (print_indices , obj = config )
46+
47+ assert result .exit_code == 0
48+ # Check that cat.indices was called with correct parameters
49+ assert cat_client .indices .calls == [
50+ pretend .call (
51+ index = "production*,staging*" ,
52+ h = "health,status,index,id,pri,rep,docs.count,docs.deleted,store.size,creation.date.string" , # noqa: E501
53+ s = "creation.date.string:desc" ,
54+ v = True ,
55+ )
56+ ]
57+ # Check that indices.get_alias was called
58+ assert indices_client .get_alias .calls == [
59+ pretend .call (index = "production*,staging*" )
60+ ]
61+ # Check output contains expected content
62+ assert "health status index" in result .output
63+ assert "Current Aliases:" in result .output
64+ assert "production -> production-2024-01-01" in result .output
65+ assert "staging -> staging-2024-01-01" in result .output
66+
67+ def test_delete_older_indices_success (self , cli ):
68+ # Mock OpenSearch client with multiple indices
69+ # Keep latest 2: production-2024-03-01 + production-2024-02-01
70+ # Delete: production-2024-01-01
71+ indices_client = pretend .stub (
72+ get_alias = pretend .call_recorder (
73+ lambda ** kw : {"production-2024-03-01" : {"aliases" : {"production" : {}}}}
74+ ),
75+ get = pretend .call_recorder (
76+ lambda ** kw : {
77+ "production-2024-03-01" : {},
78+ "production-2024-02-01" : {},
79+ "production-2024-01-01" : {},
80+ }
81+ ),
82+ delete = pretend .call_recorder (lambda ** kw : {"acknowledged" : True }),
83+ )
84+ client = pretend .stub (indices = indices_client )
85+ config = pretend .stub (registry = {"opensearch.client" : client })
86+
87+ result = cli .invoke (delete_older_indices , ["production" ], obj = config )
88+
89+ assert result .exit_code == 0
90+ # Check that get_alias was called correctly
91+ assert indices_client .get_alias .calls == [pretend .call (name = "production" )]
92+ # Check that get was called to fetch all indices
93+ assert indices_client .get .calls == [pretend .call (index = "production-*" )]
94+ # Check that delete was called only for the oldest index (keeps latest 2)
95+ assert indices_client .delete .calls == [
96+ pretend .call (index = "production-2024-01-01" ),
97+ ]
98+ # Check output
99+ assert "Current index: production-2024-03-01" in result .output
100+ assert "Found 1 older indices to delete." in result .output
101+ assert "Deleting index: production-2024-01-01" in result .output
102+ assert "Done." in result .output
103+
104+ def test_delete_older_indices_multiple_deletions (self , cli ):
105+ # Mock OpenSearch client with many indices
106+ # Keep latest 2: production-2024-05-01 + production-2024-04-01
107+ # Delete: production-2024-03-01, production-2024-02-01, production-2024-01-01
108+ indices_client = pretend .stub (
109+ get_alias = pretend .call_recorder (
110+ lambda ** kw : {"production-2024-04-01" : {"aliases" : {"production" : {}}}}
111+ ),
112+ get = pretend .call_recorder (
113+ lambda ** kw : {
114+ "production-2024-05-01" : {},
115+ "production-2024-04-01" : {},
116+ "production-2024-03-01" : {},
117+ "production-2024-02-01" : {},
118+ "production-2024-01-01" : {},
119+ }
120+ ),
121+ delete = pretend .call_recorder (lambda ** kw : {"acknowledged" : True }),
122+ )
123+ client = pretend .stub (indices = indices_client )
124+ config = pretend .stub (registry = {"opensearch.client" : client })
125+
126+ result = cli .invoke (delete_older_indices , ["production" ], obj = config )
127+
128+ assert result .exit_code == 0
129+ # Check that delete was called for all old indices (keeps latest 2)
130+ assert indices_client .delete .calls == [
131+ pretend .call (index = "production-2024-03-01" ),
132+ pretend .call (index = "production-2024-02-01" ),
133+ pretend .call (index = "production-2024-01-01" ),
134+ ]
135+ # Check output
136+ assert "Current index: production-2024-04-01" in result .output
137+ assert "Found 3 older indices to delete." in result .output
138+ assert "Done." in result .output
139+
140+ def test_delete_older_indices_no_alias (self , cli ):
141+ # Mock OpenSearch client to raise NotFoundError when alias not found
142+ def raise_not_found (** kw ):
143+ raise NotFoundError (404 , "index_not_found_exception" , "no such index" )
144+
145+ indices_client = pretend .stub (get_alias = pretend .call_recorder (raise_not_found ))
146+ client = pretend .stub (indices = indices_client )
147+ config = pretend .stub (registry = {"opensearch.client" : client })
148+
149+ result = cli .invoke (delete_older_indices , ["production" ], obj = config )
150+
151+ assert result .exit_code == 1
152+ # Check that get_alias was called
153+ assert indices_client .get_alias .calls == [pretend .call (name = "production" )]
154+ # Check error message
155+ assert "No alias found for production, aborting." in result .output
156+
157+ def test_delete_older_indices_only_current (self , cli ):
158+ # Mock OpenSearch client with only the current index (no backup, no older)
159+ indices_client = pretend .stub (
160+ get_alias = pretend .call_recorder (
161+ lambda ** kw : {"production-2024-03-01" : {"aliases" : {"production" : {}}}}
162+ ),
163+ get = pretend .call_recorder (lambda ** kw : {"production-2024-03-01" : {}}),
164+ delete = pretend .call_recorder (lambda ** kw : {"acknowledged" : True }),
165+ )
166+ client = pretend .stub (indices = indices_client )
167+ config = pretend .stub (registry = {"opensearch.client" : client })
168+
169+ result = cli .invoke (delete_older_indices , ["production" ], obj = config )
170+
171+ assert result .exit_code == 0
172+ # Check that delete was never called (only 1 index exists)
173+ assert indices_client .delete .calls == []
174+ # Check output
175+ assert "Current index: production-2024-03-01" in result .output
176+ assert "Found 0 older indices to delete." in result .output
177+ assert "Done." in result .output
178+
179+ def test_delete_older_indices_keeps_two (self , cli ):
180+ # Mock OpenSearch client with exactly 2 indices (current + 1 backup)
181+ # Should not delete anything - keeps both
182+ indices_client = pretend .stub (
183+ get_alias = pretend .call_recorder (
184+ lambda ** kw : {"production-2024-02-01" : {"aliases" : {"production" : {}}}}
185+ ),
186+ get = pretend .call_recorder (
187+ lambda ** kw : {
188+ "production-2024-02-01" : {},
189+ "production-2024-01-01" : {},
190+ }
191+ ),
192+ delete = pretend .call_recorder (lambda ** kw : {"acknowledged" : True }),
193+ )
194+ client = pretend .stub (indices = indices_client )
195+ config = pretend .stub (registry = {"opensearch.client" : client })
196+
197+ result = cli .invoke (delete_older_indices , ["production" ], obj = config )
198+
199+ assert result .exit_code == 0
200+ # Check that delete was never called (keeps latest 2)
201+ assert indices_client .delete .calls == []
202+ # Check output
203+ assert "Current index: production-2024-02-01" in result .output
204+ assert "Found 0 older indices to delete." in result .output
205+ assert "Done." in result .output
0 commit comments