@@ -217,7 +217,6 @@ private void createContinuousTransform(String indexName, String transformId, Str
217217 * Verify the basic stats API, which includes state, health, and optionally progress (if it exists).
218218 * These are required for Kibana 8.13+.
219219 */
220- @ SuppressWarnings ("unchecked" )
221220 public void testBasicContinuousTransformStats () throws Exception {
222221 var transformId = "transform-continuous-basic-stats" ;
223222 createContinuousTransform ("continuous-basic-stats-reviews" , transformId , "reviews-by-user-business-day" );
@@ -234,6 +233,50 @@ public void testBasicContinuousTransformStats() throws Exception {
234233 deleteTransform (transformId );
235234 }
236235
236+ public void testEmptySourceIndexClearsErrors () throws Exception {
237+ var sourceIndexName = "source-empty-reviews" ;
238+ var destIndexName = "destination-empty-reviews" ;
239+ var transformId = "transform-empty-source-index" ;
240+
241+ createReviewsIndexMappings (sourceIndexName , null );
242+
243+ var config = createTransformConfigBuilder (transformId , destIndexName , QueryConfig .matchAll (), sourceIndexName ).setPivotConfig (
244+ createPivotConfig (groupByUserOnly (), aggregateScoresAndTimes ())
245+ )
246+ .setSyncConfig (new TimeSyncConfig ("timestamp" , TimeValue .timeValueSeconds (1 )))
247+ .setSettings (new SettingsConfig .Builder ().setUnattended (true ).build ())
248+ .build ();
249+
250+ putTransform (transformId , Strings .toString (config ), RequestOptions .DEFAULT );
251+ startTransform (config .getId (), RequestOptions .DEFAULT );
252+
253+ waitUntilCheckpoint (config .getId (), 1L );
254+ assertEquals ("green" , getTransformHealthStatus (transformId ));
255+
256+ // this will cause the transform to fail to search
257+ assertAcknowledged (adminClient ().performRequest (new Request ("PUT" , sourceIndexName + "/_block/read" )));
258+ assertBusy (() -> assertThat (getTransformHealthStatus (transformId ), oneOf ("yellow" , "red" )), 30 , TimeUnit .SECONDS );
259+
260+ // unblock reads on the search index and the transform should recover
261+ assertAcknowledged (adminClient ().performRequest (new Request ("DELETE" , sourceIndexName + "/_block/read" )));
262+ assertBusy (() -> assertEquals ("green" , getTransformHealthStatus (transformId )), 30 , TimeUnit .SECONDS );
263+
264+ stopTransform (transformId );
265+ deleteTransform (transformId );
266+ deleteIndex (sourceIndexName );
267+ deleteIndex (destIndexName );
268+ }
269+
270+ private Map <String , SingleGroupSource > groupByUserOnly () {
271+ return Map .of ("by-user" , new TermsGroupSource ("user_id" , null , false ));
272+ }
273+
274+ private AggregatorFactories .Builder aggregateScoresAndTimes () {
275+ return AggregatorFactories .builder ()
276+ .addAggregator (AggregationBuilders .avg ("review_score" ).field ("stars" ))
277+ .addAggregator (AggregationBuilders .max ("timestamp" ).field ("timestamp" ));
278+ }
279+
237280 public void testDestinationIndexBlocked () throws Exception {
238281 var transformId = "transform-continuous-blocked-destination" ;
239282 var sourceIndexName = "source-reviews" ;
@@ -385,12 +428,8 @@ public void testContinuousTransformUpdate() throws Exception {
385428 String indexName = "continuous-reviews-update" ;
386429 createReviewsIndex (indexName , 10 , NUM_USERS , TransformIT ::getUserIdForRow , TransformIT ::getDateStringForRow );
387430
388- Map <String , SingleGroupSource > groups = new HashMap <>();
389- groups .put ("by-user" , new TermsGroupSource ("user_id" , null , false ));
390-
391- AggregatorFactories .Builder aggs = AggregatorFactories .builder ()
392- .addAggregator (AggregationBuilders .avg ("review_score" ).field ("stars" ))
393- .addAggregator (AggregationBuilders .max ("timestamp" ).field ("timestamp" ));
431+ var groups = groupByUserOnly ();
432+ var aggs = aggregateScoresAndTimes ();
394433
395434 String id = "transform-to-update" ;
396435 String dest = "reviews-by-user-business-day-to-update" ;
@@ -481,8 +520,7 @@ public void testRetentionPolicyDelete() throws Exception {
481520 String dest = "retention-policy-dest" ;
482521 createReviewsIndex (indexName , 10 , NUM_USERS , TransformIT ::getUserIdForRow , TransformIT ::getDateStringForRow );
483522
484- Map <String , SingleGroupSource > groups = new HashMap <>();
485- groups .put ("by-user" , new TermsGroupSource ("user_id" , null , false ));
523+ var groups = groupByUserOnly ();
486524
487525 AggregatorFactories .Builder aggs = AggregatorFactories .builder ()
488526 .addAggregator (AggregationBuilders .max ("timestamp" ).field ("timestamp" ));
0 commit comments