4343import static org .hamcrest .MatcherAssert .assertThat ;
4444import static org .junit .Assert .assertNull ;
4545import 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 ;
4649
4750/**
4851 * Tests for {@link Bucketer}.
@@ -440,6 +443,90 @@ public void bucketUserNotInOverlappingGroupExperiment() throws Exception {
440443 assertNull (algorithm .bucket (groupExperiment , "blah" ));
441444 }
442445
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+
443530 //======== Helper methods ========//
444531
445532 /**
@@ -455,4 +542,21 @@ int generateBucketValue(int hashCode) {
455542 }
456543 };
457544 }
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+ }
458562}
0 commit comments