@@ -327,6 +327,45 @@ public void testUsage() throws Exception {
327
327
}
328
328
}
329
329
330
+ public void testUsageWithOrphanedTask () throws Exception {
331
+ when (licenseState .isAllowed (XPackLicenseState .Feature .MACHINE_LEARNING )).thenReturn (true );
332
+ Settings .Builder settings = Settings .builder ().put (commonSettings );
333
+ settings .put ("xpack.ml.enabled" , true );
334
+
335
+ Job opened1 = buildJob ("opened1" , Collections .singletonList (buildMinDetector ("foo" )),
336
+ Collections .singletonMap ("created_by" , randomFrom ("a-cool-module" , "a_cool_module" , "a cool module" )));
337
+ GetJobsStatsAction .Response .JobStats opened1JobStats = buildJobStats ("opened1" , JobState .OPENED , 100L , 3L );
338
+ // NB: we have JobStats but no Job for "opened2"
339
+ GetJobsStatsAction .Response .JobStats opened2JobStats = buildJobStats ("opened2" , JobState .OPENED , 200L , 8L );
340
+ Job closed1 = buildJob ("closed1" , Arrays .asList (buildMinDetector ("foo" ), buildMinDetector ("bar" ), buildMinDetector ("foobar" )));
341
+ GetJobsStatsAction .Response .JobStats closed1JobStats = buildJobStats ("closed1" , JobState .CLOSED , 300L , 0 );
342
+ givenJobs (Arrays .asList (opened1 , closed1 ), Arrays .asList (opened1JobStats , opened2JobStats , closed1JobStats ));
343
+
344
+ var usageAction = newUsageAction (settings .build ());
345
+ PlainActionFuture <XPackUsageFeatureResponse > future = new PlainActionFuture <>();
346
+ usageAction .masterOperation (null , null , ClusterState .EMPTY_STATE , future );
347
+ XPackFeatureSet .Usage usage = future .get ().getUsage ();
348
+
349
+ XContentSource source ;
350
+ try (XContentBuilder builder = XContentFactory .jsonBuilder ()) {
351
+ usage .toXContent (builder , ToXContent .EMPTY_PARAMS );
352
+ source = new XContentSource (builder );
353
+ }
354
+
355
+ // The orphaned job should be excluded from the usage info
356
+ assertThat (source .getValue ("jobs._all.count" ), equalTo (2 ));
357
+ assertThat (source .getValue ("jobs._all.detectors.min" ), equalTo (1.0 ));
358
+ assertThat (source .getValue ("jobs._all.detectors.max" ), equalTo (3.0 ));
359
+ assertThat (source .getValue ("jobs._all.detectors.total" ), equalTo (4.0 ));
360
+ assertThat (source .getValue ("jobs._all.detectors.avg" ), equalTo (2.0 ));
361
+ assertThat (source .getValue ("jobs._all.model_size.min" ), equalTo (100.0 ));
362
+ assertThat (source .getValue ("jobs._all.model_size.max" ), equalTo (300.0 ));
363
+ assertThat (source .getValue ("jobs._all.model_size.total" ), equalTo (400.0 ));
364
+ assertThat (source .getValue ("jobs._all.model_size.avg" ), equalTo (200.0 ));
365
+ assertThat (source .getValue ("jobs._all.created_by.a_cool_module" ), equalTo (1 ));
366
+ assertThat (source .getValue ("jobs._all.created_by.unknown" ), equalTo (1 ));
367
+ }
368
+
330
369
public void testUsageDisabledML () throws Exception {
331
370
when (licenseState .isAllowed (XPackLicenseState .Feature .MACHINE_LEARNING )).thenReturn (true );
332
371
Settings .Builder settings = Settings .builder ().put (commonSettings );
0 commit comments