@@ -87,7 +87,7 @@ describe('EppoClient E2E test', () => {
87
87
const mockExperimentConfig = {
88
88
name : flagKey ,
89
89
enabled : true ,
90
- subjectShards : 100 ,
90
+ subjectShards : 10000 ,
91
91
overrides : { } ,
92
92
typedOverrides : { } ,
93
93
rules : [
@@ -99,32 +99,35 @@ describe('EppoClient E2E test', () => {
99
99
allocations : {
100
100
allocation1 : {
101
101
percentExposure : 1 ,
102
+ statusQuoVariationKey : null ,
103
+ shippedVariationKey : null ,
104
+ holdouts : [ ] ,
102
105
variations : [
103
106
{
104
107
name : 'control' ,
105
108
value : 'control' ,
106
109
typedValue : 'control' ,
107
110
shardRange : {
108
111
start : 0 ,
109
- end : 34 ,
112
+ end : 3333 ,
110
113
} ,
111
114
} ,
112
115
{
113
116
name : 'variant-1' ,
114
117
value : 'variant-1' ,
115
118
typedValue : 'variant-1' ,
116
119
shardRange : {
117
- start : 34 ,
118
- end : 67 ,
120
+ start : 3333 ,
121
+ end : 6667 ,
119
122
} ,
120
123
} ,
121
124
{
122
125
name : 'variant-2' ,
123
126
value : 'variant-2' ,
124
127
typedValue : 'variant-2' ,
125
128
shardRange : {
126
- start : 67 ,
127
- end : 100 ,
129
+ start : 6667 ,
130
+ end : 10000 ,
128
131
} ,
129
132
} ,
130
133
] ,
@@ -470,14 +473,17 @@ describe('EppoClient E2E test', () => {
470
473
allocations : {
471
474
allocation1 : {
472
475
percentExposure : 1 ,
476
+ statusQuoVariationKey : null ,
477
+ shippedVariationKey : null ,
478
+ holdouts : [ ] ,
473
479
variations : [
474
480
{
475
481
name : 'control' ,
476
482
value : 'control' ,
477
483
typedValue : 'control' ,
478
484
shardRange : {
479
485
start : 0 ,
480
- end : 100 ,
486
+ end : 10000 ,
481
487
} ,
482
488
} ,
483
489
{
@@ -502,6 +508,9 @@ describe('EppoClient E2E test', () => {
502
508
allocations : {
503
509
allocation1 : {
504
510
percentExposure : 1 ,
511
+ statusQuoVariationKey : null ,
512
+ shippedVariationKey : null ,
513
+ holdouts : [ ] ,
505
514
variations : [
506
515
{
507
516
name : 'control' ,
@@ -518,7 +527,7 @@ describe('EppoClient E2E test', () => {
518
527
typedValue : 'treatment' ,
519
528
shardRange : {
520
529
start : 0 ,
521
- end : 100 ,
530
+ end : 10000 ,
522
531
} ,
523
532
} ,
524
533
] ,
@@ -546,14 +555,17 @@ describe('EppoClient E2E test', () => {
546
555
allocations : {
547
556
allocation1 : {
548
557
percentExposure : 1 ,
558
+ statusQuoVariationKey : null ,
559
+ shippedVariationKey : null ,
560
+ holdouts : [ ] ,
549
561
variations : [
550
562
{
551
563
name : 'some-new-treatment' ,
552
564
value : 'some-new-treatment' ,
553
565
typedValue : 'some-new-treatment' ,
554
566
shardRange : {
555
567
start : 0 ,
556
- end : 100 ,
568
+ end : 10000 ,
557
569
} ,
558
570
} ,
559
571
] ,
@@ -596,13 +608,221 @@ describe('EppoClient E2E test', () => {
596
608
597
609
const client = new EppoClient ( storage ) ;
598
610
let assignment = client . getAssignment ( 'subject-10' , flagKey , { appVersion : 9 } ) ;
599
- expect ( assignment ) . toEqual ( null ) ;
611
+ expect ( assignment ) . toBeNull ( ) ;
600
612
assignment = client . getAssignment ( 'subject-10' , flagKey ) ;
601
- expect ( assignment ) . toEqual ( null ) ;
613
+ expect ( assignment ) . toBeNull ( ) ;
602
614
assignment = client . getAssignment ( 'subject-10' , flagKey , { appVersion : 11 } ) ;
603
615
expect ( assignment ) . toEqual ( 'control' ) ;
604
616
} ) ;
605
617
618
+ it ( 'returns control variation and logs holdout key if subject is in holdout in an experiment allocation' , ( ) => {
619
+ const entry = {
620
+ ...mockExperimentConfig ,
621
+ allocations : {
622
+ allocation1 : {
623
+ percentExposure : 1 ,
624
+ statusQuoVariationKey : 'variation-7' ,
625
+ shippedVariationKey : null ,
626
+ holdouts : [
627
+ {
628
+ holdoutKey : 'holdout-2' ,
629
+ statusQuoShardRange : {
630
+ start : 0 ,
631
+ end : 200 ,
632
+ } ,
633
+ shippedShardRange : null , // this is an experiment allocation because shippedShardRange is null
634
+ } ,
635
+ {
636
+ holdoutKey : 'holdout-3' ,
637
+ statusQuoShardRange : {
638
+ start : 200 ,
639
+ end : 400 ,
640
+ } ,
641
+ shippedShardRange : null ,
642
+ } ,
643
+ ] ,
644
+ variations : [
645
+ {
646
+ name : 'control' ,
647
+ value : 'control' ,
648
+ typedValue : 'control' ,
649
+ shardRange : {
650
+ start : 0 ,
651
+ end : 3333 ,
652
+ } ,
653
+ variationKey : 'variation-7' ,
654
+ } ,
655
+ {
656
+ name : 'variant-1' ,
657
+ value : 'variant-1' ,
658
+ typedValue : 'variant-1' ,
659
+ shardRange : {
660
+ start : 3333 ,
661
+ end : 6667 ,
662
+ } ,
663
+ variationKey : 'variation-8' ,
664
+ } ,
665
+ {
666
+ name : 'variant-2' ,
667
+ value : 'variant-2' ,
668
+ typedValue : 'variant-2' ,
669
+ shardRange : {
670
+ start : 6667 ,
671
+ end : 10000 ,
672
+ } ,
673
+ variationKey : 'variation-9' ,
674
+ } ,
675
+ ] ,
676
+ } ,
677
+ } ,
678
+ } ;
679
+
680
+ storage . setEntries ( { [ flagKey ] : entry } ) ;
681
+
682
+ const mockLogger = td . object < IAssignmentLogger > ( ) ;
683
+ const client = new EppoClient ( storage ) ;
684
+ client . setLogger ( mockLogger ) ;
685
+ td . reset ( ) ;
686
+
687
+ // subject-79 --> holdout shard is 186
688
+ let assignment = client . getAssignment ( 'subject-79' , flagKey ) ;
689
+ expect ( assignment ) . toEqual ( 'control' ) ;
690
+ // Only log holdout key (not variation) if this is an experiment allocation
691
+ expect ( td . explain ( mockLogger . logAssignment ) . calls [ 0 ] . args [ 0 ] . holdoutVariation ) . toBeNull ( ) ;
692
+ expect ( td . explain ( mockLogger . logAssignment ) . calls [ 0 ] . args [ 0 ] . holdout ) . toEqual ( 'holdout-2' ) ;
693
+
694
+ // subject-8 --> holdout shard is 201
695
+ assignment = client . getAssignment ( 'subject-8' , flagKey ) ;
696
+ expect ( assignment ) . toEqual ( 'control' ) ;
697
+ // Only log holdout key (not variation) if this is an experiment allocation
698
+ expect ( td . explain ( mockLogger . logAssignment ) . calls [ 1 ] . args [ 0 ] . holdoutVariation ) . toBeNull ( ) ;
699
+ expect ( td . explain ( mockLogger . logAssignment ) . calls [ 1 ] . args [ 0 ] . holdout ) . toEqual ( 'holdout-3' ) ;
700
+
701
+ // subject-11 --> holdout shard is 9137 (outside holdout), non-holdout assignment shard is 8414
702
+ assignment = client . getAssignment ( 'subject-11' , flagKey ) ;
703
+ expect ( assignment ) . toEqual ( 'variant-2' ) ;
704
+ expect ( td . explain ( mockLogger . logAssignment ) . calls [ 2 ] . args [ 0 ] . holdoutVariation ) . toBeNull ( ) ;
705
+ expect ( td . explain ( mockLogger . logAssignment ) . calls [ 2 ] . args [ 0 ] . holdout ) . toBeNull ( ) ;
706
+ } ) ;
707
+
708
+ it ( 'returns the shipped variation and logs holdout key and variation if subject is in holdout in a rollout allocation' , ( ) => {
709
+ const entry = {
710
+ ...mockExperimentConfig ,
711
+ allocations : {
712
+ allocation1 : {
713
+ percentExposure : 1 ,
714
+ statusQuoVariationKey : 'variation-7' ,
715
+ shippedVariationKey : 'variation-8' ,
716
+ holdouts : [
717
+ {
718
+ holdoutKey : 'holdout-2' ,
719
+ statusQuoShardRange : {
720
+ start : 0 ,
721
+ end : 100 ,
722
+ } ,
723
+ shippedShardRange : {
724
+ start : 100 ,
725
+ end : 200 ,
726
+ } ,
727
+ } ,
728
+ {
729
+ holdoutKey : 'holdout-3' ,
730
+ statusQuoShardRange : {
731
+ start : 200 ,
732
+ end : 300 ,
733
+ } ,
734
+ shippedShardRange : {
735
+ start : 300 ,
736
+ end : 400 ,
737
+ } ,
738
+ } ,
739
+ ] ,
740
+ variations : [
741
+ {
742
+ name : 'control' ,
743
+ value : 'control' ,
744
+ typedValue : 'control' ,
745
+ shardRange : {
746
+ start : 0 ,
747
+ end : 0 ,
748
+ } ,
749
+ variationKey : 'variation-7' ,
750
+ } ,
751
+ {
752
+ name : 'variant-1' ,
753
+ value : 'variant-1' ,
754
+ typedValue : 'variant-1' ,
755
+ shardRange : {
756
+ start : 0 ,
757
+ end : 0 ,
758
+ } ,
759
+ variationKey : 'variation-8' ,
760
+ } ,
761
+ {
762
+ name : 'variant-2' ,
763
+ value : 'variant-2' ,
764
+ typedValue : 'variant-2' ,
765
+ shardRange : {
766
+ start : 0 ,
767
+ end : 10000 ,
768
+ } ,
769
+ variationKey : 'variation-9' ,
770
+ } ,
771
+ ] ,
772
+ } ,
773
+ } ,
774
+ } ;
775
+
776
+ storage . setEntries ( { [ flagKey ] : entry } ) ;
777
+
778
+ const mockLogger = td . object < IAssignmentLogger > ( ) ;
779
+ const client = new EppoClient ( storage ) ;
780
+ client . setLogger ( mockLogger ) ;
781
+ td . reset ( ) ;
782
+
783
+ // subject-227 --> holdout shard is 57
784
+ let assignment = client . getAssignment ( 'subject-227' , flagKey ) ;
785
+ expect ( assignment ) . toEqual ( 'control' ) ;
786
+ // Log both holdout key and variation if this is a rollout allocation
787
+ expect ( td . explain ( mockLogger . logAssignment ) . calls [ 0 ] . args [ 0 ] . holdoutVariation ) . toEqual (
788
+ 'status_quo' ,
789
+ ) ;
790
+ expect ( td . explain ( mockLogger . logAssignment ) . calls [ 0 ] . args [ 0 ] . holdout ) . toEqual ( 'holdout-2' ) ;
791
+
792
+ // subject-79 --> holdout shard is 186
793
+ assignment = client . getAssignment ( 'subject-79' , flagKey ) ;
794
+ expect ( assignment ) . toEqual ( 'variant-1' ) ;
795
+ // Log both holdout key and variation if this is a rollout allocation
796
+ expect ( td . explain ( mockLogger . logAssignment ) . calls [ 1 ] . args [ 0 ] . holdoutVariation ) . toEqual (
797
+ 'all_shipped_variants' ,
798
+ ) ;
799
+ expect ( td . explain ( mockLogger . logAssignment ) . calls [ 1 ] . args [ 0 ] . holdout ) . toEqual ( 'holdout-2' ) ;
800
+
801
+ // subject-8 --> holdout shard is 201
802
+ assignment = client . getAssignment ( 'subject-8' , flagKey ) ;
803
+ expect ( assignment ) . toEqual ( 'control' ) ;
804
+ // Log both holdout key and variation if this is a rollout allocation
805
+ expect ( td . explain ( mockLogger . logAssignment ) . calls [ 2 ] . args [ 0 ] . holdoutVariation ) . toEqual (
806
+ 'status_quo' ,
807
+ ) ;
808
+ expect ( td . explain ( mockLogger . logAssignment ) . calls [ 2 ] . args [ 0 ] . holdout ) . toEqual ( 'holdout-3' ) ;
809
+
810
+ // subject-50 --> holdout shard is 347
811
+ assignment = client . getAssignment ( 'subject-50' , flagKey ) ;
812
+ expect ( assignment ) . toEqual ( 'variant-1' ) ;
813
+ // Log both holdout key and variation if this is a rollout allocation
814
+ expect ( td . explain ( mockLogger . logAssignment ) . calls [ 3 ] . args [ 0 ] . holdoutVariation ) . toEqual (
815
+ 'all_shipped_variants' ,
816
+ ) ;
817
+ expect ( td . explain ( mockLogger . logAssignment ) . calls [ 3 ] . args [ 0 ] . holdout ) . toEqual ( 'holdout-3' ) ;
818
+
819
+ // subject-7 --> holdout shard is 9483 (outside holdout), non-holdout assignment shard is 8673
820
+ assignment = client . getAssignment ( 'subject-7' , flagKey ) ;
821
+ expect ( assignment ) . toEqual ( 'variant-2' ) ;
822
+ expect ( td . explain ( mockLogger . logAssignment ) . calls [ 4 ] . args [ 0 ] . holdoutVariation ) . toBeNull ( ) ;
823
+ expect ( td . explain ( mockLogger . logAssignment ) . calls [ 4 ] . args [ 0 ] . holdout ) . toBeNull ( ) ;
824
+ } ) ;
825
+
606
826
function getAssignmentsWithSubjectAttributes (
607
827
subjectsWithAttributes : {
608
828
subjectKey : string ;
@@ -732,7 +952,7 @@ describe('EppoClient E2E test', () => {
732
952
} ,
733
953
) ;
734
954
735
- expect ( variation ) . not . toEqual ( null ) ;
955
+ expect ( variation ) . not . toBeNull ( ) ;
736
956
expect ( td . explain ( mockLogger . logAssignment ) . callCount ) . toEqual ( 1 ) ;
737
957
} ) ;
738
958
} ) ;
0 commit comments