ZhanwangZhou opened a new pull request, #296:
URL: https://github.com/apache/gora/pull/296

   ### Description 
   
   I encountered non-deterministic behavior while running the following tests 
using NonDex:
   
   `org.apache.gora.ignite.store.TestIgniteStore`
   
   In gora-ignite/src/main/java/org/apache/gora/ignite/utils/IgniteSQLBuilder, 
method `createInsertQuery` and `fillInsertQuery` convert the entrySet of Map 
object `data` into List object `list`:
   
   ```java
   List<Entry<Column, Object>> list = new ArrayList<>(data.entrySet());
   ```
   
   These two methods then iterate the list and pass its elements as other 
methods' parameters. The conversion from entrySet of Map to List causes the 
random order of List's element. This randomness further causes the 
non-deterministic behavior of `put` method in 
gora-ignite/src/main/java/org/apache/gora/ignite/store/IgniteStore, which calls 
these two methods. All tests calling `put` method of class `IgniteStore` are 
thus flaky.
   
   Similarly, in 
gora-ignite/src/main/java/org/apache/gora/ignite/store/IgnoreStoreMetadataAnalyzer,
 method `getTableNames` iterates an unsorted ResultSet object `executeQuery` 
and appends its elements into List of table name Strings. The order of the 
table names in the list is random, but the list is then returned and compared 
with a list with fixed order in line 42 of 
gora-ignite/src/test/java/org/apache/gora/ignite/store/TestIgniteStore
   
   ```java
   Assert.assertTrue("Ignite Store Metadata Table Names", 
createAnalyzer.getTablesNames().equals(Lists.newArrayList("WEBPAGE", 
"EMPLOYEE")));
   ```
   
   The randomness of the list returned by `getTableNames` thus may cause 
unexpected failure of TestIgniteStore.
   
   ### Steps to Reproduce
   
   I used tool NonDex to detect the flaky tests.
   
   NonDex: https://github.com/TestingResearchIllinois/NonDex
   
   Run the tests with NonDex: 
   
   ```
   mvn -pl gora-ignite edu.illinois:nondex-maven-plugin:2.1.7:nondex 
-Dtest=org.apache.gora.ignite.store.TestIgniteStore
   ```
   
   The error message shows:
   
   <details>
     <summary>Click to view</summary>
   
   
   ```
   [ERROR] Tests run: 45, Failures: 12, Errors: 17, Skipped: 0, Time elapsed: 
12.609 s <<< FAILURE! - in org.apache.gora.ignite.store.TestIgniteStore
   [ERROR] 
igniteStoreMetadataAnalyzerTest(org.apache.gora.ignite.store.TestIgniteStore)  
Time elapsed: 1.6 s  <<< FAILURE!
   java.lang.AssertionError: Ignite Store Metadata Table Names
        at 
org.apache.gora.ignite.store.TestIgniteStore.igniteStoreMetadataAnalyzerTest(TestIgniteStore.java:42)
   
   [ERROR] testQuery(org.apache.gora.ignite.store.TestIgniteStore)  Time 
elapsed: 0.339 s  <<< FAILURE!
   java.lang.AssertionError: expected:<10> but was:<0>
   
   [ERROR] testGet3UnionField(org.apache.gora.ignite.store.TestIgniteStore)  
Time elapsed: 0.402 s  <<< ERROR!
   org.apache.gora.util.GoraException: org.apache.gora.util.GoraException: 
java.sql.SQLException: Value conversion failed [column=SALARY, 
from=java.lang.String, to=java.lang.Integer]
   Caused by: org.apache.gora.util.GoraException: java.sql.SQLException: Value 
conversion failed [column=SALARY, from=java.lang.String, to=java.lang.Integer]
   Caused by: java.sql.SQLException: Value conversion failed [column=SALARY, 
from=java.lang.String, to=java.lang.Integer]
   
   [ERROR] testGetPartitions(org.apache.gora.ignite.store.TestIgniteStore)  
Time elapsed: 0.291 s  <<< FAILURE!
   java.lang.AssertionError
   
   [ERROR] testAutoCreateSchema(org.apache.gora.ignite.store.TestIgniteStore)  
Time elapsed: 0.39 s  <<< ERROR!
   org.apache.gora.util.GoraException: org.apache.gora.util.GoraException: 
java.sql.SQLException: Value conversion failed [column=SALARY, 
from=java.lang.Long, to=java.lang.Integer]
   Caused by: org.apache.gora.util.GoraException: java.sql.SQLException: Value 
conversion failed [column=SALARY, from=java.lang.Long, to=java.lang.Integer]
   Caused by: java.sql.SQLException: Value conversion failed [column=SALARY, 
from=java.lang.Long, to=java.lang.Integer]
   
   [ERROR] testBenchmarkExists(org.apache.gora.ignite.store.TestIgniteStore)  
Time elapsed: 0.371 s  <<< ERROR!
   org.apache.gora.util.GoraException: org.apache.gora.util.GoraException: 
java.sql.SQLException: Value conversion failed [column=SALARY, 
from=java.lang.String, to=java.lang.Integer]
   Caused by: org.apache.gora.util.GoraException: java.sql.SQLException: Value 
conversion failed [column=SALARY, from=java.lang.String, to=java.lang.Integer]
   Caused by: java.sql.SQLException: Value conversion failed [column=SALARY, 
from=java.lang.String, to=java.lang.Integer]
   
   [ERROR] testPutArray(org.apache.gora.ignite.store.TestIgniteStore)  Time 
elapsed: 0.271 s  <<< ERROR!
   org.apache.gora.util.GoraException: org.apache.gora.util.GoraException: 
java.sql.SQLException: Value conversion failed [column=BYTEDATA, 
from=java.lang.String, to=[B]
   Caused by: org.apache.gora.util.GoraException: java.sql.SQLException: Value 
conversion failed [column=BYTEDATA, from=java.lang.String, to=[B]
   Caused by: java.sql.SQLException: Value conversion failed [column=BYTEDATA, 
from=java.lang.String, to=[B]
   
   [ERROR] testGetNested(org.apache.gora.ignite.store.TestIgniteStore)  Time 
elapsed: 0.485 s  <<< ERROR!
   org.apache.gora.util.GoraException: org.apache.gora.util.GoraException: 
java.sql.SQLException: Value conversion failed [column=WEBPAGE, 
from=java.lang.String, to=[B]
   Caused by: org.apache.gora.util.GoraException: java.sql.SQLException: Value 
conversion failed [column=WEBPAGE, from=java.lang.String, to=[B]
   Caused by: java.sql.SQLException: Value conversion failed [column=WEBPAGE, 
from=java.lang.String, to=[B]
   
   [ERROR] 
testQueryWebPageSingleKey(org.apache.gora.ignite.store.TestIgniteStore)  Time 
elapsed: 0.186 s  <<< FAILURE!
   java.lang.AssertionError
   
   [ERROR] 
testGetWebPageDefaultFields(org.apache.gora.ignite.store.TestIgniteStore)  Time 
elapsed: 0.266 s  <<< ERROR!
   org.apache.gora.util.GoraException: java.io.EOFException
   Caused by: java.io.EOFException
   
   [ERROR] testPutNested(org.apache.gora.ignite.store.TestIgniteStore)  Time 
elapsed: 0.19 s  <<< ERROR!
   org.apache.gora.util.GoraException: org.apache.gora.util.GoraException: 
java.sql.SQLException: Value conversion failed [column=PARSEDCONTENT, 
from=java.lang.String, to=[B]
   Caused by: org.apache.gora.util.GoraException: java.sql.SQLException: Value 
conversion failed [column=PARSEDCONTENT, from=java.lang.String, to=[B]
   Caused by: java.sql.SQLException: Value conversion failed 
[column=PARSEDCONTENT, from=java.lang.String, to=[B]
   
   [ERROR] testUpdate(org.apache.gora.ignite.store.TestIgniteStore)  Time 
elapsed: 0.14 s  <<< ERROR!
   org.apache.gora.util.GoraException: org.apache.gora.util.GoraException: 
java.sql.SQLException: Value conversion failed [column=DATEOFBIRTH, 
from=java.lang.String, to=java.lang.Long]
   Caused by: org.apache.gora.util.GoraException: java.sql.SQLException: Value 
conversion failed [column=DATEOFBIRTH, from=java.lang.String, to=java.lang.Long]
   Caused by: java.sql.SQLException: Value conversion failed 
[column=DATEOFBIRTH, from=java.lang.String, to=java.lang.Long]
   
   [ERROR] 
testDeleteByQueryFields(org.apache.gora.ignite.store.TestIgniteStore)  Time 
elapsed: 0.136 s  <<< FAILURE!
   java.lang.AssertionError: expected:<10> but was:<0>
   
   [ERROR] testQueryEndKey(org.apache.gora.ignite.store.TestIgniteStore)  Time 
elapsed: 0.296 s  <<< FAILURE!
   java.lang.AssertionError: expected:<1> but was:<0>
   
   [ERROR] testGetDoubleRecursive(org.apache.gora.ignite.store.TestIgniteStore) 
 Time elapsed: 0.303 s  <<< ERROR!
   org.apache.gora.util.GoraException: org.apache.gora.util.GoraException: 
java.sql.SQLException: Value conversion failed [column=SALARY, 
from=java.lang.String, to=java.lang.Integer]
   Caused by: org.apache.gora.util.GoraException: java.sql.SQLException: Value 
conversion failed [column=SALARY, from=java.lang.String, to=java.lang.Integer]
   Caused by: java.sql.SQLException: Value conversion failed [column=SALARY, 
from=java.lang.String, to=java.lang.Integer]
   
   [ERROR] testQueryKeyRange(org.apache.gora.ignite.store.TestIgniteStore)  
Time elapsed: 0.121 s  <<< FAILURE!
   java.lang.AssertionError: expected:<1> but was:<0>
   
   [ERROR] testExists(org.apache.gora.ignite.store.TestIgniteStore)  Time 
elapsed: 0.147 s  <<< ERROR!
   org.apache.gora.util.GoraException: org.apache.gora.util.GoraException: 
java.sql.SQLException: Value conversion failed [column=SALARY, 
from=java.lang.String, to=java.lang.Integer]
   Caused by: org.apache.gora.util.GoraException: java.sql.SQLException: Value 
conversion failed [column=SALARY, from=java.lang.String, to=java.lang.Integer]
   Caused by: java.sql.SQLException: Value conversion failed [column=SALARY, 
from=java.lang.String, to=java.lang.Integer]
   
   [ERROR] 
testQueryWebPageSingleKeyDefaultFields(org.apache.gora.ignite.store.TestIgniteStore)
  Time elapsed: 0.111 s  <<< FAILURE!
   java.lang.AssertionError
   
   [ERROR] testGet(org.apache.gora.ignite.store.TestIgniteStore)  Time elapsed: 
0.107 s  <<< ERROR!
   org.apache.gora.util.GoraException: org.apache.gora.util.GoraException: 
java.sql.SQLException: Value conversion failed [column=SALARY, 
from=java.lang.String, to=java.lang.Integer]
   Caused by: org.apache.gora.util.GoraException: java.sql.SQLException: Value 
conversion failed [column=SALARY, from=java.lang.String, to=java.lang.Integer]
   Caused by: java.sql.SQLException: Value conversion failed [column=SALARY, 
from=java.lang.String, to=java.lang.Integer]
   
   [ERROR] testGetRecursive(org.apache.gora.ignite.store.TestIgniteStore)  Time 
elapsed: 0.556 s  <<< ERROR!
   org.apache.gora.util.GoraException: org.apache.gora.util.GoraException: 
java.sql.SQLException: Value conversion failed [column=SALARY, 
from=java.lang.String, to=java.lang.Integer]
   Caused by: org.apache.gora.util.GoraException: java.sql.SQLException: Value 
conversion failed [column=SALARY, from=java.lang.String, to=java.lang.Integer]
   Caused by: java.sql.SQLException: Value conversion failed [column=SALARY, 
from=java.lang.String, to=java.lang.Integer]
   
   [ERROR] testGetWithFields(org.apache.gora.ignite.store.TestIgniteStore)  
Time elapsed: 0.149 s  <<< ERROR!
   org.apache.gora.util.GoraException: org.apache.gora.util.GoraException: 
java.sql.SQLException: Value conversion failed [column=WEBPAGE, 
from=java.lang.String, to=[B]
   Caused by: org.apache.gora.util.GoraException: java.sql.SQLException: Value 
conversion failed [column=WEBPAGE, from=java.lang.String, to=[B]
   Caused by: java.sql.SQLException: Value conversion failed [column=WEBPAGE, 
from=java.lang.String, to=[B]
   
   [ERROR] testObjectFieldValue(org.apache.gora.ignite.store.TestIgniteStore)  
Time elapsed: 0.109 s  <<< ERROR!
   org.apache.gora.util.GoraException: org.apache.gora.util.GoraException: 
java.sql.SQLException: Value conversion failed [column=DATEOFBIRTH, 
from=java.lang.String, to=java.lang.Long]
   Caused by: org.apache.gora.util.GoraException: java.sql.SQLException: Value 
conversion failed [column=DATEOFBIRTH, from=java.lang.String, to=java.lang.Long]
   Caused by: java.sql.SQLException: Value conversion failed 
[column=DATEOFBIRTH, from=java.lang.String, to=java.lang.Long]
   
   [ERROR] testPutMixedMaps(org.apache.gora.ignite.store.TestIgniteStore)  Time 
elapsed: 0.118 s  <<< ERROR!
   org.apache.gora.util.GoraException: org.apache.gora.util.GoraException: 
java.sql.SQLException: Value conversion failed [column=OUTLINKS, 
from=java.lang.String, to=[B]
   Caused by: org.apache.gora.util.GoraException: java.sql.SQLException: Value 
conversion failed [column=OUTLINKS, from=java.lang.String, to=[B]
   Caused by: java.sql.SQLException: Value conversion failed [column=OUTLINKS, 
from=java.lang.String, to=[B]
   
   [ERROR] testGetWebPage(org.apache.gora.ignite.store.TestIgniteStore)  Time 
elapsed: 0.117 s  <<< FAILURE!
   java.lang.AssertionError
   
   [ERROR] testPutMap(org.apache.gora.ignite.store.TestIgniteStore)  Time 
elapsed: 0.12 s  <<< ERROR!
   org.apache.gora.util.GoraException: org.apache.gora.util.GoraException: 
java.sql.SQLException: Value conversion failed [column=PARSEDCONTENT, 
from=java.lang.String, to=[B]
   Caused by: org.apache.gora.util.GoraException: java.sql.SQLException: Value 
conversion failed [column=PARSEDCONTENT, from=java.lang.String, to=[B]
   Caused by: java.sql.SQLException: Value conversion failed 
[column=PARSEDCONTENT, from=java.lang.String, to=[B]
   
   [ERROR] testDelete(org.apache.gora.ignite.store.TestIgniteStore)  Time 
elapsed: 0.331 s  <<< FAILURE!
   java.lang.AssertionError: expected:<9> but was:<0>
   
   [ERROR] testDeleteByQuery(org.apache.gora.ignite.store.TestIgniteStore)  
Time elapsed: 0.269 s  <<< FAILURE!
   java.lang.AssertionError: expected:<10> but was:<0>
   
   [ERROR] testQueryStartKey(org.apache.gora.ignite.store.TestIgniteStore)  
Time elapsed: 0.156 s  <<< FAILURE!
   java.lang.AssertionError: expected:<10> but was:<0>
   
   [ERROR] testPutBytes(org.apache.gora.ignite.store.TestIgniteStore)  Time 
elapsed: 0.13 s  <<< ERROR!
   org.apache.gora.util.GoraException: org.apache.gora.util.GoraException: 
java.sql.SQLException: Value conversion failed [column=PARSEDCONTENT, 
from=java.lang.String, to=[B]
   Caused by: org.apache.gora.util.GoraException: java.sql.SQLException: Value 
conversion failed [column=PARSEDCONTENT, from=java.lang.String, to=[B]
   Caused by: java.sql.SQLException: Value conversion failed 
[column=PARSEDCONTENT, from=java.lang.String, to=[B]
   
   [INFO]
   [INFO] Results:
   [INFO]
   [ERROR] Failures:
   [ERROR]   TestIgniteStore.igniteStoreMetadataAnalyzerTest:42 Ignite Store 
Metadata Table Names
   [ERROR]   TestIgniteStore>DataStoreTestBase.testDelete:353 expected:<9> but 
was:<0>
   [ERROR]   TestIgniteStore>DataStoreTestBase.testDeleteByQuery:359 
expected:<10> but was:<0>
   [ERROR]   TestIgniteStore>DataStoreTestBase.testDeleteByQueryFields:365 
expected:<10> but was:<0>
   [ERROR]   TestIgniteStore>DataStoreTestBase.testGetPartitions:371
   [ERROR]   TestIgniteStore>DataStoreTestBase.testGetWebPage:293
   [ERROR]   TestIgniteStore>DataStoreTestBase.testQuery:311 expected:<10> but 
was:<0>
   [ERROR]   TestIgniteStore>DataStoreTestBase.testQueryEndKey:323 expected:<1> 
but was:<0>
   [ERROR]   TestIgniteStore>DataStoreTestBase.testQueryKeyRange:329 
expected:<1> but was:<0>
   [ERROR]   TestIgniteStore>DataStoreTestBase.testQueryStartKey:317 
expected:<10> but was:<0>
   [ERROR]   TestIgniteStore>DataStoreTestBase.testQueryWebPageSingleKey:335
   [ERROR]   
TestIgniteStore>DataStoreTestBase.testQueryWebPageSingleKeyDefaultFields:341
   [ERROR] Errors:
   [ERROR]   TestIgniteStore>DataStoreTestBase.testAutoCreateSchema:123 » Gora 
org.apache.g...
   [ERROR]   TestIgniteStore>DataStoreTestBase.testBenchmarkExists:226 » Gora 
org.apache.go...
   [ERROR]   TestIgniteStore>DataStoreTestBase.testExists:220 » Gora 
org.apache.gora.util.G...
   [ERROR]   TestIgniteStore>DataStoreTestBase.testGet:232 » Gora 
org.apache.gora.util.Gora...
   [ERROR]   TestIgniteStore>DataStoreTestBase.testGet3UnionField:281 » Gora 
org.apache.gor...
   [ERROR]   TestIgniteStore>DataStoreTestBase.testGetDoubleRecursive:256 » 
Gora org.apache...
   [ERROR]   TestIgniteStore>DataStoreTestBase.testGetNested:269 » Gora 
org.apache.gora.uti...
   [ERROR]   TestIgniteStore>DataStoreTestBase.testGetRecursive:244 » Gora 
org.apache.gora....
   [ERROR]   TestIgniteStore>DataStoreTestBase.testGetWebPageDefaultFields:299 
» Gora java....
   [ERROR]   TestIgniteStore>DataStoreTestBase.testGetWithFields:287 » Gora 
org.apache.gora...
   [ERROR]   TestIgniteStore>DataStoreTestBase.testObjectFieldValue:426 » Gora 
org.apache.g...
   [ERROR]   TestIgniteStore>DataStoreTestBase.testPutArray:169 » Gora 
org.apache.gora.util...
   [ERROR]   TestIgniteStore>DataStoreTestBase.testPutBytes:179 » Gora 
org.apache.gora.util...
   [ERROR]   TestIgniteStore>DataStoreTestBase.testPutMap:189 » Gora 
org.apache.gora.util.G...
   [ERROR]   TestIgniteStore>DataStoreTestBase.testPutMixedMaps:199 » Gora 
org.apache.gora....
   [ERROR]   TestIgniteStore>DataStoreTestBase.testPutNested:163 » Gora 
org.apache.gora.uti...
   [ERROR]   TestIgniteStore>DataStoreTestBase.testUpdate:205 » Gora 
org.apache.gora.util.G...
   [INFO]
   [ERROR] Tests run: 45, Failures: 12, Errors: 17, Skipped: 0
   ```
   
   </details>
   
   ### Potential Solution
   
   To fix the non-deterministic behavior of method `createInsertQuery` and 
`fillInsertQuery` of class `IgniteSQLBuilder`, we can pass a fix-ordered List 
instead of a random-ordered Map as parameters into these two functions:
   
   ```java
   public static String createInsertQuery(IgniteMapping mapping, List<Column> 
dataKeyList)
   public static void fillInsertQuery(PreparedStatement statement, List<Object> 
insertData)
   ```
   
   Meanwhile, in `put` method of class `IgniteStore`, we maintain two lists 
storing Map object `data`'s keys and values:
   
   ```java
   List<Column> dataKeyList = new ArrayList<>();
   List<Object> dataValueList = new ArrayList<>();
   ```
   
   Whenever we put a key-value pair into Map object `data`, we update these two 
lists by adding the key and value. Therefore, the order of elements in these 
two lists will be deterministic, exactly matching the order in which we put 
key-value pairs into Map object `data`. We can then pass these two lists into 
method `createInsertQuery` and `fillInsertQuery` and fix the non-deterministic 
behavior.
   
   To fix the non-deterministic behavior of method `getTableNames` in class 
IgnoreStoreMetadataAnalyzer, we can sort the List `tab` before returning it:
   
   ```java
   Collections.sort(tabs);
   ```
   
    Then, the order of elements in List `tab` will be deterministic, following 
alphabetical order.
   
   Correspondingly, we need to change the list for comparison in line 42 of 
`TestIgniteStore` to alphabetical order:
   
   ```java
   Assert.assertTrue("Ignite Store Metadata Table Names", 
createAnalyzer.getTablesNames().equals(Lists.newArrayList("EMPLOYEE", 
"WEBPAGE")));
   ```
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscr...@gora.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to