Skip to content

Commit

Permalink
Corrected empty bucket get assignment bug and removed extra method fr…
Browse files Browse the repository at this point in the history
…om interface Assignment
  • Loading branch information
mans4singh committed Sep 28, 2016
1 parent bf74eb3 commit ea41cdf
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,32 +83,6 @@ Assignment getAssignment(User.ID userID, Application.Name appLabel,
Experiment.Label experimentLabel, Context context, boolean createAssignment, boolean ignoreSamplingPercent,
SegmentationProfile segmentationProfile, HttpHeaders headers);

/**
* Return an existing assignment for a user, or potentially create a new
* assignment if the user is assignable to this experiment. Includes a Page.Name to identify the page through which
* the assignment was delivered.
*
* @param userID the {@link com.intuit.wasabi.assignmentobjects.User.ID} of the person we want the assignment for
* @param applicationName the {@link com.intuit.wasabi.experimentobjects.Application.Name} the app we want the assignment for
* @param label the {@link com.intuit.wasabi.experimentobjects.Experiment.Label} the experiment
* @param context the {@link Context} of the assignment call
* @param createAssignment <code>true</code> when a new Assignment should be created
* @param ignoreSamplingPercent <code>true</code> if we want to have an assignment independent of the sampling rate
* @param segmentationProfile the {@link SegmentationProfile} to be used for the assignment
* @param headers the {@link HttpHeaders} that can be used by the segmentation
* @param pageName the {@link com.intuit.wasabi.experimentobjects.Page.Name} the page name for the assignment
* @param experiment the {@link Experiment} we want the assignment for
* @param bucketList list of Buckets of this Experiment
* @param userAssignments the already existing assignments
* @param exclusives the experiments that are excluded from the assignment
* @return a brand new or old {@link Assignment}
*/
Assignment getAssignment(User.ID userID, Application.Name applicationName, Experiment.Label label, Context context,
boolean createAssignment, boolean ignoreSamplingPercent, SegmentationProfile segmentationProfile,
HttpHeaders headers, Page.Name pageName, Experiment experiment, BucketList bucketList,
Table<Experiment.ID, Experiment.Label, String> userAssignments,
Map<Experiment.ID, List<Experiment.ID>> exclusives);

/**
* Insert/update a user assignment for this experiment.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ public Assignment getSingleAssignment(User.ID userID, Application.Name applicati
}

Assignment assignment = assignmentsRepository.getAssignment(experimentID, userID, context);
if (assignment == null) {
if (assignment == null || assignment.isBucketEmpty()) {
if (createAssignment) {
if (experiment.getState() == Experiment.State.PAUSED) {
return nullAssignment(userID, applicationName, experimentID,
Expand Down Expand Up @@ -321,8 +321,7 @@ private Map<Experiment.ID, List<Experiment.ID>> getExclusivesList(Experiment.ID
* assignment if the user is assignable to this experiment. Includes a Page.Name to identify the page through which
* the assignment was delivered.
*/
@Override
public Assignment getAssignment(User.ID userID, Application.Name applicationName, Experiment.Label experimentLabel,
protected Assignment getAssignment(User.ID userID, Application.Name applicationName, Experiment.Label experimentLabel,
Context context, boolean createAssignment, boolean ignoreSamplingPercent,
SegmentationProfile segmentationProfile, HttpHeaders headers, Page.Name pageName,
Experiment experiment, BucketList bucketList,
Expand Down Expand Up @@ -357,8 +356,9 @@ public Assignment getAssignment(User.ID userID, Application.Name applicationName
Assignment.Status.EXPERIMENT_EXPIRED);
}

// FIXME - Code duplication with getSingleAssignment
Assignment assignment = getAssignment(experimentID, userID, context, userAssignments, bucketList);
if (assignment == null) {
if (assignment == null || assignment.isBucketEmpty()) {
if (createAssignment) {
if (experiment.getState() == Experiment.State.PAUSED) {
return nullAssignment(userID, applicationName, experimentID, Assignment.Status.EXPERIMENT_PAUSED);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package com.intuit.wasabi.tests.service;
/*******************************************************************************
* Copyright 2016 Intuit
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/

import static com.intuit.wasabi.tests.library.util.ModelAssert.assertEqualModelItems;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.testng.Assert;
import org.testng.annotations.Test;

import com.intuit.wasabi.tests.library.TestBase;
import com.intuit.wasabi.tests.library.util.Constants;
import com.intuit.wasabi.tests.library.util.serialstrategies.DefaultNameExclusionStrategy;
import com.intuit.wasabi.tests.library.util.serialstrategies.DefaultNameInclusionStrategy;
import com.intuit.wasabi.tests.model.Assignment;
import com.intuit.wasabi.tests.model.Bucket;
import com.intuit.wasabi.tests.model.Experiment;
import com.intuit.wasabi.tests.model.User;
import com.intuit.wasabi.tests.model.factory.AssignmentFactory;
import com.intuit.wasabi.tests.model.factory.BucketFactory;
import com.intuit.wasabi.tests.model.factory.ExperimentFactory;
import com.intuit.wasabi.tests.model.factory.UserFactory;

/**
* A test to check if user can be assigned if the previous assignment bucket is empty
*/
public class EmptyBucketGetUserAssignmentTest extends TestBase {

private Experiment experiment;
private List<Bucket> buckets = new ArrayList<>();
private User specialUser = UserFactory.createUser("SpecialForBucketTest");
private User specialUser2 = UserFactory.createUser("Special2ForBucketTest");

/**
* Initializes a default experiment.
*/
public EmptyBucketGetUserAssignmentTest() {
setResponseLogLengthLimit(1000);

experiment = ExperimentFactory.createExperiment();

DefaultNameExclusionStrategy experimentComparisonStrategy = new DefaultNameExclusionStrategy("creationTime", "modificationTime", "ruleJson");
experiment.setSerializationStrategy(experimentComparisonStrategy);

}

@Test(dependsOnGroups = {"ping"})
public void t_GetUserAssignmentEmptyBucket() {
Experiment exp = postExperiment(experiment);
Assert.assertNotNull(exp.creationTime, "Experiment creation failed (No creationTime).");
Assert.assertNotNull(exp.modificationTime, "Experiment creation failed (No modificationTime).");
Assert.assertNotNull(exp.state, "Experiment creation failed (No state).");
experiment.update(exp);
buckets = BucketFactory.createBuckets(experiment, 3);
postBuckets(buckets);

experiment.state = Constants.EXPERIMENT_STATE_RUNNING;
Experiment exp2 = putExperiment(experiment);
assertEqualModelItems(exp2, experiment);
experiment.update(exp);

// special user 2 assigned to bucket 0
Assignment assignment = AssignmentFactory.createAssignment()
.setAssignment(buckets.get(0).label)
.setExperimentLabel(experiment.label)
.setOverwrite(true);
Assignment putAssignmentFor2 = putAssignment(experiment, assignment, specialUser2);
assertEqualModelItems(putAssignmentFor2, assignment, new DefaultNameInclusionStrategy("assignment"));

// Empty bucke to which use is assigned
List<Bucket> emptyBucket = new ArrayList<>();
emptyBucket.add(buckets.get(0));
emptyBucket = putBucketsState(emptyBucket, Constants.BUCKET_STATE_EMPTY);

// Get assignment after emptying bucket
Assignment getAssignmentAfterEmpty = getAssignment(experiment, specialUser2);

Assignment assignmentForSpecialAfterReassignment = getAssignment(experiment, specialUser2);

assertEqualModelItems(assignmentForSpecialAfterReassignment, getAssignmentAfterEmpty, new DefaultNameInclusionStrategy("assignment"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.intuit.wasabi.tests.service;

import static com.intuit.wasabi.tests.library.util.ModelAssert.assertEqualModelItems;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpStatus;
import org.testng.Assert;
import org.testng.annotations.Test;

import com.intuit.wasabi.tests.library.TestBase;
import com.intuit.wasabi.tests.library.util.Constants;
import com.intuit.wasabi.tests.library.util.serialstrategies.DefaultNameExclusionStrategy;
import com.intuit.wasabi.tests.library.util.serialstrategies.DefaultNameInclusionStrategy;
import com.intuit.wasabi.tests.model.Assignment;
import com.intuit.wasabi.tests.model.Bucket;
import com.intuit.wasabi.tests.model.Experiment;
import com.intuit.wasabi.tests.model.User;
import com.intuit.wasabi.tests.model.factory.AssignmentFactory;
import com.intuit.wasabi.tests.model.factory.BucketFactory;
import com.intuit.wasabi.tests.model.factory.ExperimentFactory;
import com.intuit.wasabi.tests.model.factory.UserFactory;

/**
* A test to check if user can be assigned if the previous assignment bucket is empty
*/
public class EmptyBucketGetUserAssignmentToEmptyBucketTest extends TestBase {

private Experiment experiment;
private List<Bucket> buckets = new ArrayList<>();
private User specialUser = UserFactory.createUser("SpecialForBucketTest");

/**
* Initializes a default experiment.
*/
public EmptyBucketGetUserAssignmentToEmptyBucketTest() {
setResponseLogLengthLimit(1000);

experiment = ExperimentFactory.createExperiment();

DefaultNameExclusionStrategy experimentComparisonStrategy = new DefaultNameExclusionStrategy("creationTime", "modificationTime", "ruleJson");
experiment.setSerializationStrategy(experimentComparisonStrategy);

}

/**
* Test scenario where user is being reassigned from empty bucket to another empty bucket
*/
@Test(dependsOnGroups = {"ping"})
public void t_AddUserToExperimentWith2BucektsAndEmptyBucketBothAndReassignToAnotherEmptyBucket() {
Experiment exp = postExperiment(experiment);
Assert.assertNotNull(exp.creationTime, "Experiment creation failed.");
Assert.assertNotNull(exp.modificationTime, "Experiment creation failed (No modificationTime).");
Assert.assertNotNull(exp.state, "Experiment creation failed (No state).");
experiment.update(exp);
buckets = BucketFactory.createBuckets(experiment, 2);
postBuckets(buckets);

experiment.state = Constants.EXPERIMENT_STATE_RUNNING;
Experiment exp2 = putExperiment(experiment);
assertEqualModelItems(exp2, experiment);
experiment.update(exp);

// Assign special user to bucket 0
Assignment assignment = AssignmentFactory.createAssignment()
.setAssignment(buckets.get(0).label)
.setExperimentLabel(experiment.label)
.setOverwrite(true);
Assignment putAssignment = putAssignment(experiment, assignment, specialUser);
assertEqualModelItems(putAssignment, assignment, new DefaultNameInclusionStrategy("assignment"));

// Empty both buckets
List<Bucket> emptyBucket = new ArrayList<>();
emptyBucket.add(buckets.get(0));
emptyBucket.add(buckets.get(1));
emptyBucket = putBucketsState(emptyBucket, Constants.BUCKET_STATE_EMPTY);

// There should be no bucket available for user
Assignment getAssignmentAfterAllEmptyBuckets = getAssignment(experiment, specialUser);
Assert.assertEquals(getAssignmentAfterAllEmptyBuckets.status, Constants.NO_OPEN_BUCKETS);
}
}
2 changes: 2 additions & 0 deletions modules/functional-test/testng_integrationTests.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
<class name="com.intuit.wasabi.tests.service.IntegrationBucket" />
<class name="com.intuit.wasabi.tests.service.EmptyBucketUserAssignmentTest" />
<class name="com.intuit.wasabi.tests.service.EmptyBucketUserAssignmentToEmptyBucket" />
<class name="com.intuit.wasabi.tests.service.EmptyBucketGetUserAssignmentTest" />
<class name="com.intuit.wasabi.tests.service.EmptyBucketGetUserAssignmentToEmptyBucketTest" />
<class name="com.intuit.wasabi.tests.service.BucketIntegrationTest" />
<class name="com.intuit.wasabi.tests.service.ContextIntegrationTest" />
<class name="com.intuit.wasabi.tests.service.ContextMutexIntegrationTest" />
Expand Down

0 comments on commit ea41cdf

Please sign in to comment.