From 4a06dd919a65144ec09aa3f788b91a03aa089cec Mon Sep 17 00:00:00 2001 From: Nik Everett Date: Tue, 10 Oct 2017 10:34:03 -0400 Subject: [PATCH] Painless: add tests for cached boxing (#24163) We had a TODO about adding tests around cached boxing. In #24077 I tracked down the uncached boxing tests and saw the TODO. Cached boxing testing is a fairly small extension to that work. --- .../elasticsearch/painless/EqualsTests.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java index 9045a390f2a..30f098d28b8 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java @@ -23,7 +23,6 @@ import org.elasticsearch.test.ESTestCase; import static java.util.Collections.singletonMap; -// TODO: Figure out a way to test autobox caching properly from methods such as Integer.valueOf(int); public class EqualsTests extends ScriptTestCase { public void testTypesEquals() { assertEquals(true, exec("return false === false;")); @@ -133,7 +132,7 @@ public class EqualsTests extends ScriptTestCase { assertEquals(0, exec("def a = 1; Object b = new HashMap(); if (a === (Object)b) return 1; else return 0;")); } - public void testBranchEqualsDefAndPrimitive() { + public void testEqualsDefAndPrimitive() { /* This test needs an Integer that isn't cached by Integer.valueOf so we draw one randomly. We can't use any fixed integer because * we can never be sure that the JVM hasn't configured itself to cache that Integer. It is sneaky like that. */ int uncachedAutoboxedInt = randomValueOtherThanMany(i -> Integer.valueOf(i) == Integer.valueOf(i), ESTestCase::randomInt); @@ -141,6 +140,15 @@ public class EqualsTests extends ScriptTestCase { assertEquals(false, exec("def x = params.i; int y = params.i; return x === y;", singletonMap("i", uncachedAutoboxedInt), true)); assertEquals(true, exec("def x = params.i; int y = params.i; return y == x;", singletonMap("i", uncachedAutoboxedInt), true)); assertEquals(false, exec("def x = params.i; int y = params.i; return y === x;", singletonMap("i", uncachedAutoboxedInt), true)); + + /* Now check that we use valueOf with the boxing used for comparing primitives to def. For this we need an + * integer that is cached by Integer.valueOf. The JLS says 0 should always be cached. */ + int cachedAutoboxedInt = 0; + assertSame(Integer.valueOf(cachedAutoboxedInt), Integer.valueOf(cachedAutoboxedInt)); + assertEquals(true, exec("def x = params.i; int y = params.i; return x == y;", singletonMap("i", cachedAutoboxedInt), true)); + assertEquals(true, exec("def x = params.i; int y = params.i; return x === y;", singletonMap("i", cachedAutoboxedInt), true)); + assertEquals(true, exec("def x = params.i; int y = params.i; return y == x;", singletonMap("i", cachedAutoboxedInt), true)); + assertEquals(true, exec("def x = params.i; int y = params.i; return y === x;", singletonMap("i", cachedAutoboxedInt), true)); } public void testBranchNotEquals() { @@ -153,7 +161,7 @@ public class EqualsTests extends ScriptTestCase { assertEquals(1, exec("def a = 1; Object b = new HashMap(); if (a !== (Object)b) return 1; else return 0;")); } - public void testBranchNotEqualsDefAndPrimitive() { + public void testNotEqualsDefAndPrimitive() { /* This test needs an Integer that isn't cached by Integer.valueOf so we draw one randomly. We can't use any fixed integer because * we can never be sure that the JVM hasn't configured itself to cache that Integer. It is sneaky like that. */ int uncachedAutoboxedInt = randomValueOtherThanMany(i -> Integer.valueOf(i) == Integer.valueOf(i), ESTestCase::randomInt); @@ -161,6 +169,15 @@ public class EqualsTests extends ScriptTestCase { assertEquals(true, exec("def x = params.i; int y = params.i; return x !== y;", singletonMap("i", uncachedAutoboxedInt), true)); assertEquals(false, exec("def x = params.i; int y = params.i; return y != x;", singletonMap("i", uncachedAutoboxedInt), true)); assertEquals(true, exec("def x = params.i; int y = params.i; return y !== x;", singletonMap("i", uncachedAutoboxedInt), true)); + + /* Now check that we use valueOf with the boxing used for comparing primitives to def. For this we need an + * integer that is cached by Integer.valueOf. The JLS says 0 should always be cached. */ + int cachedAutoboxedInt = 0; + assertSame(Integer.valueOf(cachedAutoboxedInt), Integer.valueOf(cachedAutoboxedInt)); + assertEquals(false, exec("def x = params.i; int y = params.i; return x != y;", singletonMap("i", cachedAutoboxedInt), true)); + assertEquals(false, exec("def x = params.i; int y = params.i; return x !== y;", singletonMap("i", cachedAutoboxedInt), true)); + assertEquals(false, exec("def x = params.i; int y = params.i; return y != x;", singletonMap("i", cachedAutoboxedInt), true)); + assertEquals(false, exec("def x = params.i; int y = params.i; return y !== x;", singletonMap("i", cachedAutoboxedInt), true)); } public void testRightHandNull() {