43
43
import static org .hamcrest .MatcherAssert .assertThat ;
44
44
import static org .junit .Assert .assertNull ;
45
45
import static org .junit .Assert .assertTrue ;
46
+ import static org .mockito .Mockito .mock ;
47
+ import static org .mockito .Mockito .verify ;
48
+ import static org .mockito .Mockito .when ;
46
49
47
50
/**
48
51
* Tests for {@link Bucketer}.
@@ -440,6 +443,90 @@ public void bucketUserNotInOverlappingGroupExperiment() throws Exception {
440
443
assertNull (algorithm .bucket (groupExperiment , "blah" ));
441
444
}
442
445
446
+ @ Test public void bucketUserSaveActivationWithPersistentBucketer () throws Exception {
447
+ final AtomicInteger bucketValue = new AtomicInteger ();
448
+ PersistentBucketer persistentBucketer = mock (PersistentBucketer .class );
449
+ Bucketer algorithm = mockPersistentBucketAlgorith (bucketValue , persistentBucketer );
450
+ bucketValue .set (3000 );
451
+
452
+ ProjectConfig projectConfig = validProjectConfig ();
453
+ List <Experiment > groupExperiments = projectConfig .getGroups ().get (0 ).getExperiments ();
454
+ Experiment groupExperiment = groupExperiments .get (0 );
455
+ final Variation variation = groupExperiment .getVariations ().get (0 );
456
+
457
+ when (persistentBucketer .saveActivation (projectConfig , "blah" , groupExperiment , variation )).thenReturn (true );
458
+
459
+ assertThat (algorithm .bucket (groupExperiment , "blah" ), is (variation ));
460
+
461
+ logbackVerifier .expectMessage (Level .INFO ,
462
+ "Persisted variation \" e2_vtag1\" of experiment \" group_etag2\" ." );
463
+
464
+ verify (persistentBucketer ).saveActivation (projectConfig , "blah" , groupExperiment , variation );
465
+ }
466
+
467
+ @ Test public void bucketUserSaveActivationFailWithPersistentBucketer () throws Exception {
468
+ final AtomicInteger bucketValue = new AtomicInteger ();
469
+ PersistentBucketer persistentBucketer = mock (PersistentBucketer .class );
470
+ Bucketer algorithm = mockPersistentBucketAlgorith (bucketValue , persistentBucketer );
471
+ bucketValue .set (3000 );
472
+
473
+ ProjectConfig projectConfig = validProjectConfig ();
474
+ List <Experiment > groupExperiments = projectConfig .getGroups ().get (0 ).getExperiments ();
475
+ Experiment groupExperiment = groupExperiments .get (0 );
476
+ final Variation variation = groupExperiment .getVariations ().get (0 );
477
+
478
+ when (persistentBucketer .saveActivation (projectConfig , "blah" , groupExperiment , variation )).thenReturn (false );
479
+
480
+ assertThat (algorithm .bucket (groupExperiment , "blah" ), is (variation ));
481
+
482
+ logbackVerifier .expectMessage (Level .WARN ,
483
+ "Failed to persist variation \" e2_vtag1\" of experiment \" group_etag2\" ." );
484
+
485
+ verify (persistentBucketer ).saveActivation (projectConfig , "blah" , groupExperiment , variation );
486
+ }
487
+
488
+ @ Test public void bucketUserRestoreActivationWithPersistentBucketer () throws Exception {
489
+ final AtomicInteger bucketValue = new AtomicInteger ();
490
+ PersistentBucketer persistentBucketer = mock (PersistentBucketer .class );
491
+ Bucketer algorithm = mockPersistentBucketAlgorith (bucketValue , persistentBucketer );
492
+ bucketValue .set (3000 );
493
+
494
+ ProjectConfig projectConfig = validProjectConfig ();
495
+ List <Experiment > groupExperiments = projectConfig .getGroups ().get (0 ).getExperiments ();
496
+ Experiment groupExperiment = groupExperiments .get (0 );
497
+ final Variation variation = groupExperiment .getVariations ().get (0 );
498
+
499
+ when (persistentBucketer .restoreActivation (projectConfig , "blah" , groupExperiment )).thenReturn (variation );
500
+
501
+ assertThat (algorithm .bucket (groupExperiment , "blah" ), is (variation ));
502
+
503
+ logbackVerifier .expectMessage (Level .INFO ,
504
+ "Returning previously activated variation \" e2_vtag1\" from persistent bucketer." );
505
+
506
+ verify (persistentBucketer ).restoreActivation (projectConfig , "blah" , groupExperiment );
507
+ }
508
+
509
+ @ Test public void bucketUserRestoreActivationNullWithPersistentBucketer () throws Exception {
510
+ final AtomicInteger bucketValue = new AtomicInteger ();
511
+ PersistentBucketer persistentBucketer = mock (PersistentBucketer .class );
512
+ Bucketer algorithm = mockPersistentBucketAlgorith (bucketValue , persistentBucketer );
513
+ bucketValue .set (3000 );
514
+
515
+ ProjectConfig projectConfig = validProjectConfig ();
516
+ List <Experiment > groupExperiments = projectConfig .getGroups ().get (0 ).getExperiments ();
517
+ Experiment groupExperiment = groupExperiments .get (0 );
518
+ final Variation variation = groupExperiment .getVariations ().get (0 );
519
+
520
+ when (persistentBucketer .restoreActivation (projectConfig , "blah" , groupExperiment )).thenReturn (null );
521
+
522
+ assertThat (algorithm .bucket (groupExperiment , "blah" ), is (variation ));
523
+
524
+ logbackVerifier .expectMessage (Level .INFO ,
525
+ "No previously activated variation returned from persistent bucketer." );
526
+
527
+ verify (persistentBucketer ).restoreActivation (projectConfig , "blah" , groupExperiment );
528
+ }
529
+
443
530
//======== Helper methods ========//
444
531
445
532
/**
@@ -455,4 +542,21 @@ int generateBucketValue(int hashCode) {
455
542
}
456
543
};
457
544
}
545
+
546
+ /**
547
+ * Sets up a mock algorithm that returns an expected bucket value.
548
+ *
549
+ * Includes a composed {@link PersistentBucketer} mock instance
550
+ *
551
+ * @param bucketValue the expected bucket value holder
552
+ * @return the mock bucket algorithm
553
+ */
554
+ private Bucketer mockPersistentBucketAlgorith (final AtomicInteger bucketValue , final PersistentBucketer persistentBucketer ) {
555
+ return new Bucketer (validProjectConfig (), persistentBucketer ) {
556
+ @ Override
557
+ int generateBucketValue (int hashCode ) {
558
+ return bucketValue .get ();
559
+ }
560
+ };
561
+ }
458
562
}
0 commit comments