Skip to content

Commit e985f2c

Browse files
Irina/sonarjava 4396 (#4317)
1 parent 3edf049 commit e985f2c

File tree

12 files changed

+706
-130
lines changed

12 files changed

+706
-130
lines changed

java-checks-testkit/src/test/java/org/sonar/java/checks/verifier/internal/InternalCheckVerifierTest.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@
1919
*/
2020
package org.sonar.java.checks.verifier.internal;
2121

22+
import java.io.File;
23+
import java.io.IOException;
2224
import java.nio.file.Path;
25+
import java.security.NoSuchAlgorithmException;
2326
import java.util.Arrays;
2427
import java.util.Collections;
2528
import java.util.List;
@@ -33,6 +36,7 @@
3336
import org.sonar.check.Rule;
3437
import org.sonar.java.AnalysisException;
3538
import org.sonar.java.caching.DummyCache;
39+
import org.sonar.java.caching.FileHashingUtils;
3640
import org.sonar.java.caching.JavaReadCacheImpl;
3741
import org.sonar.java.caching.JavaWriteCacheImpl;
3842
import org.sonar.java.reporting.AnalyzerMessage;
@@ -950,9 +954,10 @@ void addFiles_throws_an_IllegalArgumentException_if_file_added_before() {
950954
}
951955

952956
@Test
953-
void withCache_effectively_sets_the_caches_for_scanWithoutParsing() {
954-
ReadCache readCache = new InternalReadCache();
955-
WriteCache writeCache = new InternalWriteCache();
957+
void withCache_effectively_sets_the_caches_for_scanWithoutParsing() throws IOException, NoSuchAlgorithmException {
958+
InputFile inputFile = InternalInputFile.inputFile("", new File(TEST_FILE), InputFile.Status.SAME);
959+
ReadCache readCache = new InternalReadCache().put("java:contentHash:MD5::" + TEST_FILE, FileHashingUtils.inputFileContentHash(inputFile));
960+
WriteCache writeCache = new InternalWriteCache().bind(readCache);
956961
CacheContext cacheContext = new InternalCacheContext(
957962
true,
958963
new JavaReadCacheImpl(readCache),

java-checks/src/test/java/org/sonar/java/checks/MissingPackageInfoCheckTest.java

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@
1919
*/
2020
package org.sonar.java.checks;
2121

22-
import java.io.IOException;
23-
import java.io.InputStream;
24-
import java.util.Set;
2522
import org.junit.jupiter.api.BeforeEach;
2623
import org.junit.jupiter.api.Test;
2724
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -30,15 +27,20 @@
3027
import org.sonar.api.utils.log.LogTesterJUnit5;
3128
import org.sonar.api.utils.log.LoggerLevel;
3229
import org.sonar.java.AnalysisException;
30+
import org.sonar.java.caching.FileHashingUtils;
31+
import org.sonar.java.checks.helpers.HashCacheTestHelper;
3332
import org.sonar.java.checks.verifier.CheckVerifier;
3433
import org.sonar.java.checks.verifier.internal.InternalReadCache;
3534
import org.sonar.java.checks.verifier.internal.InternalWriteCache;
36-
import org.sonar.plugins.java.api.InputFileScannerContext;
37-
import org.sonar.plugins.java.api.JavaFileScannerContext;
35+
36+
import java.io.ByteArrayInputStream;
37+
import java.io.IOException;
38+
import java.io.InputStream;
39+
import java.security.NoSuchAlgorithmException;
40+
import java.util.Set;
3841

3942
import static org.assertj.core.api.Assertions.assertThat;
4043
import static org.assertj.core.api.Assertions.assertThatThrownBy;
41-
import static org.assertj.core.api.Assertions.in;
4244
import static org.mockito.ArgumentMatchers.any;
4345
import static org.mockito.Mockito.doReturn;
4446
import static org.mockito.Mockito.doThrow;
@@ -98,6 +100,7 @@ void caching() {
98100
mainCodeSourcesPath("checks/packageInfo/nopackageinfo/nopackageinfo.java")
99101
)
100102
.withCheck(new MissingPackageInfoCheck())
103+
.withCache(readCache, writeCache)
101104
.verifyIssueOnProject(EXPECTED_MESSAGE);
102105

103106
var check = spy(new MissingPackageInfoCheck());
@@ -119,26 +122,30 @@ void caching() {
119122
verify(check, times(0)).scanFile(any());
120123
verify(check, times(5)).scanWithoutParsing(any());
121124
assertThat(writeCache2.getData())
122-
.hasSize(5)
125+
.hasSizeGreaterThanOrEqualTo(5)
123126
.containsExactlyInAnyOrderEntriesOf(writeCache.getData());
124127
}
125128

126129
@Test
127-
void cache_deserialization_throws_IOException() throws IOException {
130+
void cache_deserialization_throws_IOException() throws IOException, NoSuchAlgorithmException {
131+
String filePath = mainCodeSourcesPath("checks/packageInfo/HelloWorld.java");
132+
InputFile cachedFile = HashCacheTestHelper.inputFileFromPath(filePath);
133+
byte[] cachedHash = FileHashingUtils.inputFileContentHash(cachedFile);
128134
var inputStream = mock(InputStream.class);
129135
doThrow(new IOException()).when(inputStream).readAllBytes();
130-
var readCache = mock(ReadCache.class);
131-
doReturn(inputStream).when(readCache).read(any());
132-
doReturn(true).when(readCache).contains(any());
133-
134-
var verifier = CheckVerifier.newVerifier()
135-
.withCache(readCache, writeCache)
136-
.addFiles(InputFile.Status.SAME,
137-
mainCodeSourcesPath("checks/packageInfo/HelloWorld.java")
138-
)
136+
var localReadCache = mock(ReadCache.class);
137+
InternalWriteCache localWriteCache = new InternalWriteCache().bind(localReadCache);
138+
doReturn(inputStream).when(localReadCache).read("java:S1228;S4032:package:" + cachedFile.key());
139+
doReturn(true).when(localReadCache).contains(any());
140+
doReturn(new ByteArrayInputStream(cachedHash))
141+
.when(localReadCache).read("java:contentHash:MD5:" + cachedFile.key());
142+
143+
var localVerifier = CheckVerifier.newVerifier()
144+
.withCache(localReadCache, localWriteCache)
145+
.addFiles(InputFile.Status.SAME, filePath)
139146
.withCheck(new MissingPackageInfoCheck());
140147

141-
assertThatThrownBy(verifier::verifyNoIssues)
148+
assertThatThrownBy(localVerifier::verifyNoIssues)
142149
.isInstanceOf(AnalysisException.class)
143150
.hasRootCauseInstanceOf(IOException.class);
144151
}
@@ -159,17 +166,19 @@ void write_cache_multiple_writes() {
159166
}
160167

161168
@Test
162-
void emptyCache() {
169+
void emptyCache() throws NoSuchAlgorithmException, IOException {
163170
logTester.setLevel(LoggerLevel.TRACE);
164-
verifier
165-
.addFiles(InputFile.Status.SAME,
166-
mainCodeSourcesPath("checks/packageInfo/HelloWorld.java")
167-
)
171+
String filePath = mainCodeSourcesPath("checks/packageInfo/HelloWorld.java");
172+
ReadCache populatedReadCache = HashCacheTestHelper.internalReadCacheFromFile(filePath);
173+
CheckVerifier.newVerifier()
174+
.addFiles(InputFile.Status.SAME, filePath)
175+
.withCache(populatedReadCache, new InternalWriteCache().bind(populatedReadCache))
168176
.withCheck(new MissingPackageInfoCheck())
169177
.verifyNoIssues();
170178

171179
assertThat(logTester.logs(LoggerLevel.TRACE).stream()
172180
.filter(msg -> msg.matches("Cache miss for key '[^']+'")))
173181
.hasSize(1);
174182
}
183+
175184
}

java-checks/src/test/java/org/sonar/java/checks/UselessPackageInfoCheckTest.java

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
*/
2020
package org.sonar.java.checks;
2121

22+
import java.io.ByteArrayInputStream;
2223
import java.io.IOException;
2324
import java.io.InputStream;
25+
import java.security.NoSuchAlgorithmException;
2426
import org.junit.jupiter.api.BeforeEach;
2527
import org.junit.jupiter.api.Test;
2628
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -29,7 +31,8 @@
2931
import org.sonar.api.utils.log.LogTesterJUnit5;
3032
import org.sonar.api.utils.log.LoggerLevel;
3133
import org.sonar.java.AnalysisException;
32-
import org.sonar.java.caching.CacheReadException;
34+
import org.sonar.java.caching.FileHashingUtils;
35+
import org.sonar.java.checks.helpers.HashCacheTestHelper;
3336
import org.sonar.java.checks.verifier.CheckVerifier;
3437
import org.sonar.java.checks.verifier.internal.InternalReadCache;
3538
import org.sonar.java.checks.verifier.internal.InternalWriteCache;
@@ -106,19 +109,24 @@ void defaultPackage() {
106109

107110
@Test
108111
void caching() throws IOException, ClassNotFoundException {
112+
String changedFilePath1 = mainCodeSourcesPath("checks/UselessPackageInfoCheck/packageWithNoOtherFilesButNotPackageInfo/package-info.java");
113+
String changedFilePath2 = mainCodeSourcesPath("checks/UselessPackageInfoCheck/packageWithNoOtherFiles/package-info.java");
109114
verifier
110115
.onFiles(
111116
mainCodeSourcesPath("checks/UselessPackageInfoCheck/packageWithNoOtherFilesButNotPackageInfo/HelloWorld1.java"),
112117
mainCodeSourcesPath("checks/UselessPackageInfoCheck/packageWithNoOtherFilesButNotPackageInfo/HelloWorld2.java"),
113-
mainCodeSourcesPath("checks/UselessPackageInfoCheck/packageWithNoOtherFilesButNotPackageInfo/package-info.java"),
114-
mainCodeSourcesPath("checks/UselessPackageInfoCheck/packageWithNoOtherFiles/package-info.java")
118+
changedFilePath1,
119+
changedFilePath2
115120
)
116121
.withCheck(new UselessPackageInfoCheck())
122+
.withCache(readCache, writeCache)
117123
.verifyIssueOnFile("Remove this package.");
118124

119125
var check = spy(new UselessPackageInfoCheck());
120126

121127
var populatedReadCache = new InternalReadCache().putAll(writeCache);
128+
populatedReadCache.put(HashCacheTestHelper.contentHashKey(changedFilePath1), new byte[0]);
129+
populatedReadCache.put(HashCacheTestHelper.contentHashKey(changedFilePath2), new byte[0]);
122130
var writeCache2 = new InternalWriteCache().bind(populatedReadCache);
123131
CheckVerifier.newVerifier()
124132
.withCache(populatedReadCache, writeCache2)
@@ -127,32 +135,37 @@ void caching() throws IOException, ClassNotFoundException {
127135
mainCodeSourcesPath("checks/UselessPackageInfoCheck/packageWithNoOtherFilesButNotPackageInfo/HelloWorld2.java")
128136
)
129137
.addFiles(InputFile.Status.CHANGED,
130-
mainCodeSourcesPath("checks/UselessPackageInfoCheck/packageWithNoOtherFilesButNotPackageInfo/package-info.java"),
131-
mainCodeSourcesPath("checks/UselessPackageInfoCheck/packageWithNoOtherFiles/package-info.java")
138+
changedFilePath1,
139+
changedFilePath2
132140
)
133141
.withCheck(check)
134142
.verifyIssueOnFile("Remove this package.");
135143

136144
verify(check, times(2)).scanFile(any());
137145
verify(check, times(2)).scanWithoutParsing(any());
138146
assertThat(writeCache2.getData())
139-
.hasSize(4)
147+
.hasSizeGreaterThanOrEqualTo(4)
140148
.containsExactlyInAnyOrderEntriesOf(writeCache.getData());
141149
}
142150

143151
@Test
144-
void cache_deserialization_throws_IOException() throws IOException {
152+
void cache_deserialization_throws_IOException() throws IOException, NoSuchAlgorithmException {
145153
var inputStream = mock(InputStream.class);
146154
doThrow(new IOException()).when(inputStream).readAllBytes();
147-
var readCache = mock(ReadCache.class);
148-
doReturn(inputStream).when(readCache).read(any());
149-
doReturn(true).when(readCache).contains(any());
155+
var localReadCache = mock(ReadCache.class);
156+
157+
String filePath = mainCodeSourcesPath("checks/UselessPackageInfoCheck/packageWithNoOtherFilesButNotPackageInfo/HelloWorld1.java");
158+
InputFile cachedFile = HashCacheTestHelper.inputFileFromPath(filePath);
159+
byte[] cachedHash = FileHashingUtils.inputFileContentHash(cachedFile);
160+
161+
doReturn(inputStream).when(localReadCache).read("java:S1228;S4032:package:"+cachedFile.key());
162+
doReturn(true).when(localReadCache).contains(any());
163+
doReturn(new ByteArrayInputStream(cachedHash))
164+
.when(localReadCache).read("java:contentHash:MD5:"+cachedFile.key());
150165

151166
var verifier = CheckVerifier.newVerifier()
152-
.withCache(readCache, writeCache)
153-
.addFiles(InputFile.Status.SAME,
154-
mainCodeSourcesPath("checks/UselessPackageInfoCheck/packageWithNoOtherFilesButNotPackageInfo/HelloWorld1.java")
155-
)
167+
.withCache(localReadCache, new InternalWriteCache().bind(localReadCache))
168+
.addFiles(InputFile.Status.SAME, filePath)
156169
.withCheck(new UselessPackageInfoCheck());
157170

158171
assertThatThrownBy(verifier::verifyNoIssues)
@@ -176,13 +189,14 @@ void write_cache_multiple_writes() {
176189
}
177190

178191
@Test
179-
void emptyCache() {
192+
void emptyCache() throws NoSuchAlgorithmException, IOException {
180193
logTester.setLevel(LoggerLevel.TRACE);
194+
String filePath = mainCodeSourcesPath("checks/UselessPackageInfoCheck/packageWithNoOtherFilesButNotPackageInfo/HelloWorld1.java");
195+
ReadCache populatedReadCache = HashCacheTestHelper.internalReadCacheFromFile(filePath);
181196
verifier
182-
.addFiles(InputFile.Status.SAME,
183-
mainCodeSourcesPath("checks/UselessPackageInfoCheck/packageWithNoOtherFilesButNotPackageInfo/HelloWorld1.java")
184-
)
197+
.addFiles(InputFile.Status.SAME, filePath)
185198
.withCheck(new UselessPackageInfoCheck())
199+
.withCache(populatedReadCache, new InternalWriteCache().bind(populatedReadCache))
186200
.verifyNoIssues();
187201

188202
assertThat(logTester.logs(LoggerLevel.TRACE).stream()
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* SonarQube Java
3+
* Copyright (C) 2012-2022 SonarSource SA
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
package org.sonar.java.checks.helpers;
21+
22+
import java.io.File;
23+
import java.io.IOException;
24+
import java.security.NoSuchAlgorithmException;
25+
import java.util.Arrays;
26+
import java.util.Collection;
27+
import org.sonar.api.batch.fs.InputFile;
28+
import org.sonar.api.batch.sensor.cache.ReadCache;
29+
import org.sonar.java.caching.FileHashingUtils;
30+
import org.sonar.java.checks.verifier.internal.InternalInputFile;
31+
import org.sonar.java.checks.verifier.internal.InternalReadCache;
32+
33+
public class HashCacheTestHelper {
34+
35+
public static InputFile inputFileFromPath(String path) {
36+
return InternalInputFile
37+
.inputFile("", new File(path), InputFile.Status.SAME);
38+
}
39+
40+
public static String contentHashKey(String path) {
41+
return contentHashKey(inputFileFromPath(path));
42+
}
43+
44+
public static String contentHashKey(InputFile inputFile) {
45+
return "java:contentHash:MD5:" + inputFile.key();
46+
}
47+
48+
public static ReadCache internalReadCacheFromFile(String path) throws NoSuchAlgorithmException, IOException {
49+
InputFile cachedFile = inputFileFromPath(path);
50+
byte[] cachedHash = FileHashingUtils.inputFileContentHash(cachedFile);
51+
InternalReadCache localReadCache = new InternalReadCache().put(contentHashKey(cachedFile), cachedHash);
52+
return localReadCache;
53+
}
54+
55+
public static ReadCache internalReadCacheFromFiles(Collection<String> paths) throws NoSuchAlgorithmException, IOException {
56+
InternalReadCache localReadCache = new InternalReadCache();
57+
for (String path : paths) {
58+
InputFile cachedFile = inputFileFromPath(path);
59+
byte[] cachedHash = FileHashingUtils.inputFileContentHash(cachedFile);
60+
localReadCache.put(contentHashKey(cachedFile), cachedHash);
61+
}
62+
return localReadCache;
63+
}
64+
65+
public static byte[] getSlightlyDifferentContentHash(String path) throws NoSuchAlgorithmException, IOException {
66+
InputFile cachedFile = inputFileFromPath(path);
67+
byte[] cachedHash = FileHashingUtils.inputFileContentHash(cachedFile);
68+
byte[] copy = Arrays.copyOf(cachedHash, cachedHash.length+1);
69+
copy[cachedHash.length] = 10;
70+
return copy;
71+
}
72+
73+
}

0 commit comments

Comments
 (0)