@@ -252,8 +252,6 @@ public void bucketUserInForcedVariation() throws Exception {
252
252
assertThat (algorithm .bucket (experiment , "testUser1" ).getKey (), is ("var1" ));
253
253
}
254
254
255
-
256
-
257
255
/**
258
256
* Verify that {@link Bucketer#bucket(Experiment, String)} returns the proper variation when the user doesn't
259
257
* have a forced variation mapping.
@@ -447,10 +445,14 @@ public void bucketUserNotInOverlappingGroupExperiment() throws Exception {
447
445
assertNull (algorithm .bucket (groupExperiment , "blah" ));
448
446
}
449
447
450
- @ Test public void bucketUserSaveActivationWithPersistentBucketer () throws Exception {
448
+ /**
449
+ * Verify that {@link Bucketer#bucket(Experiment,String} saves a variation of an experiment for a user
450
+ * when a {@link UserExperimentRecord} is present.
451
+ */
452
+ @ Test public void bucketUserSaveActivationWithUserExperimentRecord () throws Exception {
451
453
final AtomicInteger bucketValue = new AtomicInteger ();
452
454
UserExperimentRecord userExperimentRecord = mock (UserExperimentRecord .class );
453
- Bucketer algorithm = mockPersistentBucketAlgorithm (bucketValue , userExperimentRecord );
455
+ Bucketer algorithm = mockUserExperimentRecordAlgorithm (bucketValue , userExperimentRecord );
454
456
bucketValue .set (3000 );
455
457
456
458
ProjectConfig projectConfig = validProjectConfig ();
@@ -463,15 +465,19 @@ public void bucketUserNotInOverlappingGroupExperiment() throws Exception {
463
465
assertThat (algorithm .bucket (groupExperiment , "blah" ), is (variation ));
464
466
465
467
logbackVerifier .expectMessage (Level .INFO ,
466
- "Persisted variation \" e2_vtag1\" of experiment \" group_etag2\" ." );
468
+ "Saved variation \" e2_vtag1\" of experiment \" group_etag2\" for user \" blah \" ." );
467
469
468
470
verify (userExperimentRecord ).save ("blah" , groupExperiment .getKey (), variation .getKey ());
469
471
}
470
472
471
- @ Test public void bucketUserSaveActivationFailWithPersistentBucketer () throws Exception {
473
+ /**
474
+ * Verify that {@link Bucketer#bucket(Experiment,String} logs correctly
475
+ * when a {@link UserExperimentRecord} is present and fails to save an activation.
476
+ */
477
+ @ Test public void bucketUserSaveActivationFailWithUserExperimentRecord () throws Exception {
472
478
final AtomicInteger bucketValue = new AtomicInteger ();
473
479
UserExperimentRecord userExperimentRecord = mock (UserExperimentRecord .class );
474
- Bucketer algorithm = mockPersistentBucketAlgorithm (bucketValue , userExperimentRecord );
480
+ Bucketer algorithm = mockUserExperimentRecordAlgorithm (bucketValue , userExperimentRecord );
475
481
bucketValue .set (3000 );
476
482
477
483
ProjectConfig projectConfig = validProjectConfig ();
@@ -484,15 +490,19 @@ public void bucketUserNotInOverlappingGroupExperiment() throws Exception {
484
490
assertThat (algorithm .bucket (groupExperiment , "blah" ), is (variation ));
485
491
486
492
logbackVerifier .expectMessage (Level .WARN ,
487
- "Failed to persist variation \" e2_vtag1\" of experiment \" group_etag2\" ." );
493
+ "Failed to save variation \" e2_vtag1\" of experiment \" group_etag2\" for user \" blah \" ." );
488
494
489
495
verify (userExperimentRecord ).save ("blah" , groupExperiment .getKey (), variation .getKey ());
490
496
}
491
497
492
- @ Test public void bucketUserRestoreActivationWithPersistentBucketer () throws Exception {
498
+ /**
499
+ * Verify that {@link Bucketer#bucket(Experiment,String)} returns a variation that is
500
+ * stored in the provided {@link userExperimentRecord}.
501
+ */
502
+ @ Test public void bucketUserRestoreActivationWithUserExperimentRecord () throws Exception {
493
503
final AtomicInteger bucketValue = new AtomicInteger ();
494
504
UserExperimentRecord userExperimentRecord = mock (UserExperimentRecord .class );
495
- Bucketer algorithm = mockPersistentBucketAlgorithm (bucketValue , userExperimentRecord );
505
+ Bucketer algorithm = mockUserExperimentRecordAlgorithm (bucketValue , userExperimentRecord );
496
506
bucketValue .set (3000 );
497
507
498
508
ProjectConfig projectConfig = validProjectConfig ();
@@ -505,15 +515,20 @@ public void bucketUserNotInOverlappingGroupExperiment() throws Exception {
505
515
assertThat (algorithm .bucket (groupExperiment , "blah" ), is (variation ));
506
516
507
517
logbackVerifier .expectMessage (Level .INFO ,
508
- "Returning previously activated variation \" e2_vtag1\" from user experiment registry." );
518
+ "Returning previously activated variation \" e2_vtag1\" of experiment \" group_etag2\" "
519
+ + " for user \" blah\" from user experiment record." );
509
520
510
521
verify (userExperimentRecord ).lookup ("blah" , groupExperiment .getKey ());
511
522
}
512
523
513
- @ Test public void bucketUserRestoreActivationNullWithPersistentBucketer () throws Exception {
524
+ /**
525
+ * Verify {@link Bucketer#bucket(Experiment,String)} handles a present {@link UserExperimentRecord}
526
+ * returning null when looking up a variation.
527
+ */
528
+ @ Test public void bucketUserRestoreActivationNullWithUserExperimentRecord () throws Exception {
514
529
final AtomicInteger bucketValue = new AtomicInteger ();
515
530
UserExperimentRecord userExperimentRecord = mock (UserExperimentRecord .class );
516
- Bucketer algorithm = mockPersistentBucketAlgorithm (bucketValue , userExperimentRecord );
531
+ Bucketer algorithm = mockUserExperimentRecordAlgorithm (bucketValue , userExperimentRecord );
517
532
bucketValue .set (3000 );
518
533
519
534
ProjectConfig projectConfig = validProjectConfig ();
@@ -525,73 +540,87 @@ public void bucketUserNotInOverlappingGroupExperiment() throws Exception {
525
540
526
541
assertThat (algorithm .bucket (groupExperiment , "blah" ), is (variation ));
527
542
528
- logbackVerifier .expectMessage (Level .INFO ,
529
- "No previously activated variation returned from persistent bucketer." );
530
-
543
+ logbackVerifier .expectMessage (Level .INFO , "No previously activated variation of experiment " +
544
+ "\" group_etag2\" for user \" blah\" found in user experiment record." );
531
545
verify (userExperimentRecord ).lookup ("blah" , groupExperiment .getKey ());
532
546
}
533
547
548
+ /**
549
+ * Verify {@link Bucketer#cleanUserExperimentRecords()} handles a null {@link UserExperimentRecord}.
550
+ */
534
551
@ Test
535
552
public void nullUserExperimentRecordWhenCleaning () {
536
553
final AtomicInteger bucketValue = new AtomicInteger ();
537
554
Bucketer algorithm = mockBucketAlgorithm (bucketValue );
538
555
bucketValue .set (3000 );
539
556
try {
540
- algorithm .cleanUserExperimentRecord ();
557
+ algorithm .cleanUserExperimentRecords ();
541
558
} catch (NullPointerException e ) {
542
559
fail ();
543
560
}
544
561
}
545
562
563
+ /**
564
+ * Verify {@link Bucketer#cleanUserExperimentRecords()} handles a null returned from
565
+ * {@link UserExperimentRecord#getAllRecords()}.
566
+ */
546
567
@ Test
547
568
public void nullUserExperimentRecords () {
548
569
final AtomicInteger bucketValue = new AtomicInteger ();
549
570
UserExperimentRecord userExperimentRecord = mock (UserExperimentRecord .class );
550
- Bucketer algorithm = mockPersistentBucketAlgorithm (bucketValue , userExperimentRecord );
571
+ Bucketer algorithm = mockUserExperimentRecordAlgorithm (bucketValue , userExperimentRecord );
551
572
bucketValue .set (3000 );
552
573
553
- when (userExperimentRecord .records ()).thenReturn (null );
574
+ when (userExperimentRecord .getAllRecords ()).thenReturn (null );
554
575
try {
555
- algorithm .cleanUserExperimentRecord ();
576
+ algorithm .cleanUserExperimentRecords ();
556
577
} catch (NullPointerException e ) {
557
578
fail ();
558
579
}
559
580
}
560
581
582
+ /**
583
+ * Verify {@link Bucketer#cleanUserExperimentRecords()} removes experiments
584
+ * that are no longer in the {@link ProjectConfig}.
585
+ */
561
586
@ Test
562
587
public void cleanRemovesRecordsOfExperimentsThatNoLongerExist () {
563
588
final AtomicInteger bucketValue = new AtomicInteger ();
564
589
UserExperimentRecord userExperimentRecord = mock (UserExperimentRecord .class );
565
- Bucketer algorithm = mockPersistentBucketAlgorithm (bucketValue , userExperimentRecord );
590
+ Bucketer algorithm = mockUserExperimentRecordAlgorithm (bucketValue , userExperimentRecord );
566
591
bucketValue .set (3000 );
567
592
568
593
Map <String ,Map <String ,String >> records = new HashMap <String , Map <String , String >>();
569
594
Map <String ,String > activation = new HashMap <String , String >();
570
- activation .put ("57 " , "57 " );
595
+ activation .put ("exp1 " , "var1 " );
571
596
records .put ("blah" , activation );
572
- when (userExperimentRecord .records ()).thenReturn (records );
597
+ when (userExperimentRecord .getAllRecords ()).thenReturn (records );
573
598
574
- algorithm .cleanUserExperimentRecord ();
599
+ algorithm .cleanUserExperimentRecords ();
575
600
576
- verify (userExperimentRecord ).remove ("blah" , "57 " );
601
+ verify (userExperimentRecord ).remove ("blah" , "exp1 " );
577
602
}
578
603
604
+ /**
605
+ * Verify {@link Bucketer#cleanUserExperimentRecords()} removes experiments
606
+ * that are paused in the {@link ProjectConfig}.
607
+ */
579
608
@ Test
580
609
public void cleanRemovesRecordsOfExperimentsThatAreNotRunning () {
581
610
final AtomicInteger bucketValue = new AtomicInteger ();
582
611
UserExperimentRecord userExperimentRecord = mock (UserExperimentRecord .class );
583
- Bucketer algorithm = mockPersistentBucketAlgorithm (bucketValue , userExperimentRecord );
612
+ Bucketer algorithm = mockUserExperimentRecordAlgorithm (bucketValue , userExperimentRecord );
584
613
bucketValue .set (3000 );
585
614
586
615
Map <String ,Map <String ,String >> records = new HashMap <String , Map <String , String >>();
587
616
Map <String ,String > activation = new HashMap <String , String >();
588
- activation .put ("118 " , "57 " );
617
+ activation .put ("exp1 " , "var1 " );
589
618
records .put ("blah" , activation );
590
- when (userExperimentRecord .records ()).thenReturn (records );
619
+ when (userExperimentRecord .getAllRecords ()).thenReturn (records );
591
620
592
- algorithm .cleanUserExperimentRecord ();
621
+ algorithm .cleanUserExperimentRecords ();
593
622
594
- verify (userExperimentRecord ).remove ("blah" , "118 " );
623
+ verify (userExperimentRecord ).remove ("blah" , "exp1 " );
595
624
}
596
625
597
626
//======== Helper methods ========//
@@ -618,12 +647,12 @@ int generateBucketValue(int hashCode) {
618
647
* @param bucketValue the expected bucket value holder
619
648
* @return the mock bucket algorithm
620
649
*/
621
- private Bucketer mockPersistentBucketAlgorithm (final AtomicInteger bucketValue , final UserExperimentRecord userExperimentRecord ) {
650
+ private Bucketer mockUserExperimentRecordAlgorithm (final AtomicInteger bucketValue , final UserExperimentRecord userExperimentRecord ) {
622
651
return new Bucketer (validProjectConfig (), userExperimentRecord ) {
623
652
@ Override
624
653
int generateBucketValue (int hashCode ) {
625
654
return bucketValue .get ();
626
655
}
627
656
};
628
657
}
629
- }
658
+ }
0 commit comments