@@ -45,6 +45,136 @@ def tearDown(self):
4545 self .source_client .drop_database (self .db_name )
4646 self .dest_client .drop_database (self .db_name )
4747
48+ def test_optimize_compound_indexes_true (self ):
49+ """
50+ Test that the migrate_schema method optimizes compound indexes.
51+ """
52+ # Create the source collection and index information
53+ source_collection = self .source_client [self .db_name ]["test_optimize" ]
54+ source_collection .create_index ([("a" , 1 ), ("b" , 1 ), ("c" , 1 ), ("d" , 1 )])
55+ source_collection .create_index ([("a" , 1 ), ("b" , 1 ), ("c" , 1 )])
56+ source_collection .create_index ([("b" , 1 ), ("c" , 1 )])
57+ source_collection .create_index ([("c" , 1 ), ("d" , 1 )])
58+ source_collection .create_index ([("b" , 1 ), ("d" , 1 )])
59+ source_collection .create_index ([("d" , 1 )])
60+
61+ collection_config_sections = []
62+ collection_config_sections .append (CollectionConfigSection ([f'{ self .db_name } .*' ], [], False , False , True ))
63+ migrate_all_config = json .loads (self ._generate_config (collection_config_sections ))
64+ collection_configs = JsonParser (migrate_all_config , self .source_client ).parse_json ()
65+
66+ # Create a SchemaMigration instance and call migrate_schema
67+ schema_migration = SchemaMigration ()
68+ schema_migration .migrate_schema (self .source_client , self .dest_client , collection_configs )
69+
70+ # Verify that the indexes were optimized in the destination collection
71+ dest_collection = self .dest_client [self .db_name ]["test_optimize" ]
72+ dest_indexes = dest_collection .index_information ()
73+ self .assertIn ("a_1_b_1_c_1_d_1" , dest_indexes , "Compound index on 'a', 'b', 'c', 'd' was not migrated successfully." )
74+ self .assertIn ("b_1_d_1" , dest_indexes , "Compound index on 'b' and 'd' was not migrated successfully." )
75+ self .assertIn ("d_1" , dest_indexes , "Compound index on 'd' was not migrated successfully." )
76+ self .assertNotIn ("a_1_b_1_c_1" , dest_indexes , "Compound index on 'a', 'b', 'c' was not optimized successfully." )
77+ self .assertNotIn ("b_1_c_1" , dest_indexes , "Compound index on 'b' and 'c' was not optimized successfully." )
78+ self .assertNotIn ("c_1_d_1" , dest_indexes , "Compound index on 'c' and 'd' was not optimized successfully." )
79+
80+ def test_optimize_compound_indexes_false (self ):
81+ """
82+ Test that the migrate_schema method doesn't optimizes compound indexes.
83+ """
84+ # Create the source collection and index information
85+ source_collection = self .source_client [self .db_name ]["test_optimize" ]
86+ source_collection .create_index ([("a" , 1 ), ("b" , 1 ), ("c" , 1 ), ("d" , 1 )])
87+ source_collection .create_index ([("a" , 1 ), ("b" , 1 ), ("c" , 1 )])
88+ source_collection .create_index ([("b" , 1 ), ("c" , 1 )])
89+ source_collection .create_index ([("c" , 1 ), ("d" , 1 )])
90+ source_collection .create_index ([("b" , 1 ), ("d" , 1 )])
91+ source_collection .create_index ([("d" , 1 )])
92+
93+ collection_config_sections = []
94+ collection_config_sections .append (CollectionConfigSection ([f'{ self .db_name } .*' ], [], False , False , False ))
95+ migrate_all_config = json .loads (self ._generate_config (collection_config_sections ))
96+ collection_configs = JsonParser (migrate_all_config , self .source_client ).parse_json ()
97+
98+ # Create a SchemaMigration instance and call migrate_schema
99+ schema_migration = SchemaMigration ()
100+ schema_migration .migrate_schema (self .source_client , self .dest_client , collection_configs )
101+
102+ # Verify that the indexes were not optimized in the destination collection
103+ dest_collection = self .dest_client [self .db_name ]["test_optimize" ]
104+ dest_indexes = dest_collection .index_information ()
105+ self .assertIn ("a_1_b_1_c_1_d_1" , dest_indexes , "Compound index on 'a', 'b', 'c', 'd' was not migrated successfully." )
106+ self .assertIn ("a_1_b_1_c_1" , dest_indexes , "Compound index on 'a', 'b', 'c' was not migrated successfully." )
107+ self .assertIn ("b_1_c_1" , dest_indexes , "Compound index on 'b' and 'c' was not migrated successfully." )
108+ self .assertIn ("c_1_d_1" , dest_indexes , "Compound index on 'c' and 'd' was not migrated successfully." )
109+ self .assertIn ("b_1_d_1" , dest_indexes , "Compound index on 'b' and 'd' was not migrated successfully." )
110+ self .assertIn ("d_1" , dest_indexes , "Compound index on 'd' was not migrated successfully." )
111+
112+ def test_optimize_compound_indexes_filters_index_with_options (self ):
113+ """
114+ Test that the migrate_schema method doesn't optimizes compound indexes when it has options.
115+ """
116+ # Create the source collection and index information
117+ self .source_client [self .db_name ].command ({
118+ 'customAction' : 'CreateCollection' ,
119+ 'collection' : 'test_optimize' ,
120+ 'indexes' : [{ 'key' : { 'a' : 1 , 'b' : 1 , 'c' : 1 }, 'name' : 'a_1_b_1_c_1' , 'unique' : True }]
121+ })
122+ self .source_client [self .db_name ]['test_optimize' ].create_index ([("a" , 1 ), ("b" , 1 ), ("c" , 1 ), ("d" , 1 )])
123+
124+ collection_config_sections = []
125+ collection_config_sections .append (CollectionConfigSection ([f'{ self .db_name } .*' ], [], False , False , True ))
126+ migrate_all_config = json .loads (self ._generate_config (collection_config_sections ))
127+ collection_configs = JsonParser (migrate_all_config , self .source_client ).parse_json ()
128+
129+ # Create a SchemaMigration instance and call migrate_schema
130+ schema_migration = SchemaMigration ()
131+ schema_migration .migrate_schema (self .source_client , self .dest_client , collection_configs )
132+
133+ # Verify that the indexes were created in the destination collection
134+ dest_collection = self .dest_client [self .db_name ]["test_optimize" ]
135+ dest_indexes = dest_collection .index_information ()
136+ self .assertIn ("a_1_b_1_c_1_d_1" , dest_indexes , "Compound index on 'a', 'b', 'c', 'd' was not migrated successfully." )
137+ self .assertIn ("a_1_b_1_c_1" , dest_indexes , "Compound index on 'a', 'b', 'c' was not migrated successfully." )
138+ self .assertEqual (dest_indexes ["a_1_b_1_c_1" ]["unique" ], True , "Unique option is not set." )
139+
140+ def test_optimize_compound_indexes_filters_index_with_other_indexes (self ):
141+ """
142+ Test that the migrate_schema method doesn't optimizes compound indexes when it has options.
143+ """
144+ # Create the source collection and index information
145+ self .source_client [self .db_name ].command ({
146+ 'customAction' : 'CreateCollection' ,
147+ 'collection' : 'test_optimize' ,
148+ 'indexes' : [
149+ { 'key' : { 'a' : 1 , 'b' : 1 , 'c' : 1 }, 'name' : 'a_1_b_1_c_1' , 'unique' : True },
150+ { 'key' : { 'b' : 1 , 'c' : 1 }, 'name' : 'b_1_c_1' , 'unique' : True , 'partialFilterExpression' : {"a" : {"$gt" : 0 }}}
151+ ]
152+ })
153+ source_collection = self .source_client [self .db_name ]['test_optimize' ]
154+ source_collection .create_index ([("a" , 1 ), ("b" , 1 ), ("c" , 1 ), ("d" , 1 )])
155+ source_collection .create_index ([("a" , 1 ), ("b" , 1 )])
156+ source_collection .create_index ([("d" , 1 )], expireAfterSeconds = 10 )
157+
158+ collection_config_sections = []
159+ collection_config_sections .append (CollectionConfigSection ([f'{ self .db_name } .*' ], [], False , False , True ))
160+ migrate_all_config = json .loads (self ._generate_config (collection_config_sections ))
161+ collection_configs = JsonParser (migrate_all_config , self .source_client ).parse_json ()
162+
163+ # Create a SchemaMigration instance and call migrate_schema
164+ schema_migration = SchemaMigration ()
165+ schema_migration .migrate_schema (self .source_client , self .dest_client , collection_configs )
166+
167+ # Verify that the indexes in destination
168+ dest_collection = self .dest_client [self .db_name ]["test_optimize" ]
169+ dest_indexes = dest_collection .index_information ()
170+ self .assertIn ("a_1_b_1_c_1_d_1" , dest_indexes , "Compound index on 'a', 'b', 'c', 'd' was not migrated successfully." )
171+ self .assertIn ("a_1_b_1_c_1" , dest_indexes , "Compound index on 'a', 'b', 'c' was not migrated successfully." )
172+ self .assertEqual (dest_indexes ["a_1_b_1_c_1" ]["unique" ], True , "Unique option is not set." )
173+ self .assertIn ("b_1_c_1" , dest_indexes , "Compound index on 'b' and 'c' was not migrated successfully." )
174+ self .assertTrue ("partialFilterExpression" in dest_indexes ["b_1_c_1" ], "Partial filter expression is not set." )
175+ self .assertIn ("d_1" , dest_indexes , "Compound index on 'd' was not migrated successfully." )
176+ self .assertEqual (dest_indexes ["d_1" ]["expireAfterSeconds" ], 10 , "TTL index on 'd' field has incorrect expireAfterSeconds." )
177+
48178 def test_ts_ttl_throws_error (self ):
49179 """
50180 Test that the migrate_schema method throws an error when a TTL index is created on a _ts field.
0 commit comments