Conversation
msridhar
left a comment
There was a problem hiding this comment.
Overall looking good! I have a few comments. Also, we need to write a test for this new code. You can add it in the AnalysisScopeTest class: https://github.com/wala/WALA/blob/master/core/src/test/java/com/ibm/wala/core/tests/cha/AnalysisScopeTest.java#L21-L21 The test should create an AnalysisScope and then confirm the JSON generated by toJSON() matches what we expect
|
|
||
|
|
||
| // import com.google.gson.Gson; |
| } | ||
|
|
||
| public String toJson() { | ||
| HashMap<String, Object> res = new HashMap<>(); |
There was a problem hiding this comment.
For this code, let's used LinkedHashMap instead of HashMap to ensure a deterministic iteration order https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html
| }; | ||
| } | ||
| } | ||
| } No newline at end of file |
| "found unexpected class"); | ||
| } | ||
| } | ||
| } No newline at end of file |
| validateDistributionUrl=true | ||
| zipStoreBase=GRADLE_USER_HOME | ||
| zipStorePath=wrapper/dists | ||
| zipStorePath=wrapper/dists No newline at end of file |
| String[] exclusions = getExclusions().toString().split("\\|"); | ||
| ArrayList<String> arr2 = new ArrayList<>(); | ||
| for(int i = 0; i < exclusions.length; i++){ | ||
| String word = exclusions[i]; | ||
| word = word.replace("(", ""); | ||
| word = word.replace(")", ""); | ||
| arr2.add(word); | ||
| } |
There was a problem hiding this comment.
Cool, way to go the extra mile to parse the exclusions!
| }; | ||
| } | ||
| } | ||
| } No newline at end of file |
| // new FileProvider().getFile("J2SEClassHierarchyExclusions.txt"), | ||
| new FileProvider().getFile("GUIExclusions.txt"), | ||
| AnalysisScopeTest.class.getClassLoader()); | ||
| String exp = "{\"Loaders\":{\"Primordial\":[\"JarFileModule:/opt/homebrew/Cellar/openjdk/21.0.1/libexec/openjdk.jdk/Contents/Home/jmods/java.base.jmod\",\"Nested Jar File:primordial.jar.model\"],\"Extension\":[],\"Application\":[\"JarFileModule:/Users/aakgna/Documents/WALA-Research/WALA/core/build/resources/test/com.ibm.wala.core.testdata_1.0.0.jar\"],\"Synthetic\":[]},\"Exclusions\":[\"java\\\\/awt\\\\/.*\",\"javax\\\\/swing\\\\/.*\",\"sun\\\\/awt\\\\/.*\",\"sun\\\\/swing\\\\/.*\"]}"; |
There was a problem hiding this comment.
This is looking better! But I expect this test will not pass in general, since we have absolute paths in it. So I guess a straightforward string comparison won't work. Here's an alternate approach:
- Call
scope.toJson()to get the JSON string - Re-parse this String using Gson
- Check that specific parts of the resulting
Mapmatch what we expect
Can you try that? Let me know if it doesn't make sense
msridhar
left a comment
There was a problem hiding this comment.
Almost there! A couple more comments on the tests
| assertEquals(arr2, map.get("Exclusions")); | ||
| } | ||
| Type type2 = new TypeToken<LinkedHashMap<String, ArrayList<String>>>(){}.getType(); | ||
| LinkedHashMap<String, ArrayList<String>> loaders = gson.fromJson(gson.toJson(map.get("Loaders")), type2); |
There was a problem hiding this comment.
Here I am confused, why do you need to serialize the data in the map back to JSON and then parse it again? I think you can get rid of this and just use some downcasts to get the data you want out of the map directly
| LinkedHashMap<String, Object> map = gson.fromJson(scope.toJson(), type); | ||
| System.out.println(map); | ||
| if(map.containsKey("Exclusions")) { | ||
| String[] exclusions = scope.getExclusions().toString().split("\\|"); |
There was a problem hiding this comment.
Here we know what is in GUIExclusions.txt. So I think we can simplify this code. We can just do something like assertEquals(List.of("java\/awt\/.*", "javax\/swing\/.*", "sun\/awt\/.*", "sun\/swing\/.*"), map.get("Exclusions")). We can then get rid of this whole loop that re-parses the exclusions string
| } | ||
| Type type2 = new TypeToken<LinkedHashMap<String, ArrayList<String>>>(){}.getType(); | ||
| LinkedHashMap<String, ArrayList<String>> loaders = gson.fromJson(gson.toJson(map.get("Loaders")), type2); | ||
| if(loaders.containsKey("Primordial")) { |
There was a problem hiding this comment.
Again we can simplify this code. We know the contents of wala.testdata.txt:
Primordial,Java,stdlib,base
Primordial,Java,jarFile,primordial.jar.model
Application,Java,jarFile,com.ibm.wala.core.testdata_1.0.0.jar
So I think we can write assertions like:
- The keys of
loadersshould be exactly"Primordial","Application","Extension","Synthetic" - Extension and Synthetic should be mapped to empty lists
- Primordial should be mapped to a list of length two. And one of the elements should contain `"primordial.jar.model"
- Application should be mapped to a list of length 1, and that element should contain
"com.ibm.wala.core.testdata_1.0.0.jar"
| LinkedHashMap<String, ArrayList<String>> loaders = new LinkedHashMap<>(); | ||
| for (ClassLoaderReference loader : loadersByName.values()) { | ||
| ArrayList<String> arr = new ArrayList<>(); | ||
|
|
| AnalysisScope tempScope = | ||
| AnalysisScopeReader.instance.readJavaScope( | ||
| TestConstants.WALA_TESTDATA, | ||
| new FileProvider().getFile("GUIExclusions.txt"), | ||
| AnalysisScopeTest.class.getClassLoader()); |
There was a problem hiding this comment.
We don't need to create this temp scope just to test the exclusions. Just skip testing the exclusions here
| scope.setExclusions(tempScope.getExclusions()); | ||
| String[] stdlibs = WalaProperties.getJ2SEJarFiles(); | ||
| Arrays.sort(stdlibs); | ||
| int cnt = 0; |
There was a problem hiding this comment.
Add a comment explaining why you are stopping at 5. Also the value 5 should be stored in a local variable and then that variable should be used in multiple places
There was a problem hiding this comment.
But this code would be simpler if you just got rid of the cnt variable and added everything. Is there any reason to add the limit?
| assertThat( | ||
| loaders.get("Primordial"), | ||
| hasItem( | ||
| "JarFileModule:/Users/aakgna/Library/Java/JavaVirtualMachines/corretto-11.0.15/Contents/Home/jmods/java.base.jmod")); |
There was a problem hiding this comment.
This check will not pass on other machines. You have the stdlibs array above. You should use the strings there (which give the full paths to the jars where the tests are running) to check that the right strings are in the JSON.
| .get("Primordial") | ||
| .get(0) | ||
| .contains( | ||
| "Java/JavaVirtualMachines/corretto-11.0.15/Contents/Home/jmods/java.base.jmod")); |
There was a problem hiding this comment.
This does not fully address my comment. Please take the paths directly from the stdlibs array and check that they match.
| new HashSet<>(List.of("Primordial", "Extension", "Application", "Synthetic")); | ||
| assertEquals(loaders.keySet(), loaderKeys); | ||
| assertEquals(stdlibs.length, loaders.get("Primordial").size()); | ||
| assertTrue(loaders.get("Primordial").get(0).contains("/Contents/Home/jmods/java.base.jmod")); |
There was a problem hiding this comment.
This is still wrong, and tests are still failing. You need to take the relevant strings from the stdlibs array for this comparison, rather than just doing get(0) and comparing to a constant string.
Added a new function to serialize an
AnalysisScopeto JSON format.