Skip to content

fix(number validation): Don't track NaN, Infinity, -Infinity, or > 2^53 #249

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jan 25, 2019

Conversation

mnoman09
Copy link
Contributor

Summary

  • Allow targeting Long and float values
  • Don't target Values > 2^53.
  • Modified isValidNumber to check if the number is smaller then 2^53 and checking instanceOf float and long attribute value.

Test plan

@coveralls
Copy link

Pull Request Test Coverage Report for Build 804

  • 17 of 20 (85.0%) changed or added relevant lines in 2 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-0.05%) to 89.721%

Changes Missing Coverage Covered Lines Changed/Added Lines %
core-api/src/main/java/com/optimizely/ab/config/audience/match/MatchType.java 4 7 57.14%
Totals Coverage Status
Change from base Build 801: -0.05%
Covered Lines: 2706
Relevant Lines: 3016

💛 - Coveralls

@coveralls
Copy link

coveralls commented Dec 21, 2018

Pull Request Test Coverage Report for Build 861

  • 18 of 19 (94.74%) changed or added relevant lines in 5 files are covered.
  • 5 unchanged lines in 3 files lost coverage.
  • Overall coverage decreased (-0.2%) to 89.545%

Changes Missing Coverage Covered Lines Changed/Added Lines %
core-api/src/main/java/com/optimizely/ab/internal/AttributesUtil.java 8 9 88.89%
Files with Coverage Reduction New Missed Lines %
core-api/src/main/java/com/optimizely/ab/config/audience/match/ExactNumberMatch.java 1 87.5%
core-api/src/main/java/com/optimizely/ab/config/audience/match/GTMatch.java 2 77.78%
core-api/src/main/java/com/optimizely/ab/config/audience/match/LTMatch.java 2 77.78%
Totals Coverage Status
Change from base Build 859: -0.2%
Covered Lines: 2715
Relevant Lines: 3032

💛 - Coveralls

return Math.abs((Long) conditionValue) <= Math.pow(2, 53);
} else if (conditionValue instanceof Float) {
Float value = ((Number) conditionValue).floatValue();
return !(value.isNaN() || value.isInfinite() || value > Math.pow(2, 53));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both validations look same for double and float, please consolidate into one.

} else if (conditionValue instanceof Double) {
Double value = ((Number) conditionValue).doubleValue();
return !(value.isNaN() || value.isInfinite());
return !(value.isNaN() || value.isInfinite() || value > Math.pow(2, 53));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Math.abs missing or double doesn't take -ve values?

@@ -218,4 +217,19 @@ public LogEvent createConversionEvent(@Nonnull ProjectConfig projectConfig,

return attributesList;
}

private static boolean isValidNumber(Object conditionValue) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/optimizely/java-sdk/pull/249/files#diff-922db348b1c4d7acd0c13f647f829eb6R73

we have two methods with same name, same functionality, can't it go into single helper method.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add documentation of this method.

* causing an exception to be thrown and passing only the valid attributes.
*/
@Test
public void createConversionEventIgnoresInvalidAndAcceptsValidValueOfValidTypeAttributes() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add -ve value cases.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

too long method name, please make it bit shorter.

@@ -72,10 +72,15 @@ public static MatchType getMatchType(String matchType, Object conditionValue) {

private static boolean isValidNumber(Object conditionValue) {
if (conditionValue instanceof Integer) {
return Math.abs((Integer) conditionValue) <= 1e53;
return Math.abs((Integer) conditionValue) <= Math.pow(2, 53);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add documentation of this method.

@msohailhussain msohailhussain requested review from mikeproeng37 and a team January 3, 2019 05:45
# Conflicts:
#	core-api/src/main/java/com/optimizely/ab/event/internal/EventFactory.java
@nchilada nchilada changed the title feat(attribute_value): Don't target NAN, INF, -INF and > 2^53 fix(number validation): Don't track NaN, Infinity, -Infinity, or > 2^53 Jan 15, 2019
@nchilada
Copy link
Contributor

Hi, sorry for the delayed code review. Could we please revive this PR? In addition to merging master (which will include changes from #228), I think we need to

Copy link
Contributor

@aliabbasrizvi aliabbasrizvi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You will have to rebase and adjust the new test.

* causing an exception to be thrown and passing only the valid attributes.
*/
@Test
public void createConversionEventIgnoresInvalidAcceptValidValOfValidAttr() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you will have to adjust this test to accommodate changes from: #250

The expectation is that there will be no decisions and enrich_decisions should be set to true

* causing an exception to be thrown and passing only the valid attributes.
*/
@Test
public void createConversionEventIgnoresNegativeInvalidAndAcceptsValidValueOfValidTypeAttributes() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar feedback as above.

@nchilada
Copy link
Contributor

Thanks for the updates! The new code looks good. But I just realized that when we evaluate targeting conditions, we probably ought to call isValidNumber on the user attribute value and not just on the condition value. We're only doing the latter right now.

Copy link
Contributor

@nchilada nchilada left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. Thanks for updating!

@nchilada
Copy link
Contributor

@mnoman09 do you think you could pull in latest master? I think we may have time to approve and merge this now. Sorry for the delays!

Copy link
Contributor

@aliabbasrizvi aliabbasrizvi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM other than the nits.

Please address.


// Bucket to the first variation for all experiments. However, only a subset of the experiments will actually
// call the bucket function.
for (Experiment experiment : allExperiments) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need this for loop now right?

assertEquals(impression.getVisitors().get(0).getAttributes().get(0).getKey(), boolAttribute.getKey());
assertEquals(impression.getVisitors().get(0).getAttributes().get(0).getValue(), validBoolAttribute);
assertEquals(impression.getVisitors().get(0).getAttributes().get(1).getKey(), validFloatAttribute.getKey());
//In below condition I am checking Value of float with double value because impression gets visitors from json so that converts it into double
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit. Change this to:

In the condition below we are checking Value of float with double value because impression gets visitors from JSON so that converts it into double

attributes,
eventTagMap);

EventBatch impression = gson.fromJson(conversionEvent.getBody(), EventBatch.class);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you calling this impression? Shouldn't this be called conversion?


// Bucket to the first variation for all experiments. However, only a subset of the experiments will actually
// call the bucket function.
for (Experiment experiment : allExperiments) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again. This is not needed right.

attributes,
eventTagMap);

EventBatch impression = gson.fromJson(conversionEvent.getBody(), EventBatch.class);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should technically be called conversion and not impression right?

# Conflicts:
#	core-api/src/main/java/com/optimizely/ab/config/audience/match/GTMatch.java
#	core-api/src/main/java/com/optimizely/ab/config/audience/match/LTMatch.java
@aliabbasrizvi aliabbasrizvi merged commit ea63898 into master Jan 25, 2019
@aliabbasrizvi aliabbasrizvi deleted the mnoman/NAN-INFCheck branch January 25, 2019 22:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants