Changeset 18816 in josm for trunk/test/unit/org/openstreetmap
- Timestamp:
- 2023-08-22T17:26:18+02:00 (16 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/test/unit/org/openstreetmap/josm/io/OsmJsonReaderTest.java
r18723 r18816 15 15 import java.time.Instant; 16 16 import java.util.Iterator; 17 import java.util.concurrent.atomic.AtomicBoolean; 17 import java.util.function.Supplier; 18 import java.util.stream.Stream; 18 19 19 20 import jakarta.json.JsonException; 20 21 21 22 import org.junit.jupiter.api.Test; 23 import org.junit.jupiter.params.ParameterizedTest; 24 import org.junit.jupiter.params.provider.Arguments; 25 import org.junit.jupiter.params.provider.MethodSource; 22 26 import org.openstreetmap.josm.data.coor.LatLon; 23 27 import org.openstreetmap.josm.data.osm.DataSet; … … 29 33 import org.openstreetmap.josm.testutils.annotations.BasicPreferences; 30 34 import org.openstreetmap.josm.tools.ExceptionUtil; 35 import org.openstreetmap.josm.tools.JosmRuntimeException; 31 36 32 37 /** … … 255 260 } 256 261 262 static Stream<Arguments> testException() { 263 final byte[] smallJson = "{\"type\", \"node\", \"id\": 1, \"lat\": 1.0, \"lon\": 2.0}".getBytes(StandardCharsets.UTF_8); 264 return Stream.of( 265 // Check that a SocketException is properly reported 266 Arguments.of(IllegalDataException.class, new ThrowableInputStream<>(() -> new SocketException("Read timed out"), smallJson), 267 "java.net.SocketException: Read timed out"), 268 // Check that a random JsonException is reported 269 Arguments.of(JsonException.class, new ThrowableInputStream<>(() -> new JsonException("Some random json exception"), smallJson), 270 "Some random json exception"), 271 // Check that bad data still throws an IllegalDataException 272 Arguments.of(IllegalDataException.class, new ThrowableInputStream<>(() -> null, smallJson), 273 "jakarta.json.stream.JsonParsingException: Invalid token=COMMA at (line no=1, column no=8, offset=7). " + 274 "Expected tokens are: [COLON]"), 275 // Check that an IOException is properly thrown when the stream is closed 276 Arguments.of(IllegalDataException.class, new ThrowableInputStream<>(() -> new JsonException("I/O error while parsing JSON", 277 new IOException("stream is closed")), smallJson), "java.io.IOException: stream is closed") 278 ); 279 } 257 280 258 281 /** … … 266 289 * </ul> 267 290 */ 268 @SuppressWarnings("resource") 269 @Test 270 void testException() { 271 final ByteArrayInputStream bais = 272 new ByteArrayInputStream("{\"type\", \"node\", \"id\": 1, \"lat\": 1.0, \"lon\": 2.0}".getBytes(StandardCharsets.UTF_8)); 273 final AtomicBoolean throwJson = new AtomicBoolean(); 274 final InputStream socketExceptionStream = new InputStream() { 275 int read = 0; // Necessary, since otherwise the exception might not be wrapped in a Json exception 276 @Override 277 public int read() throws IOException { 278 try { 279 if (read > 0 && !throwJson.get()) { 280 throw new SocketException("Read timed out"); 281 } else if (read > 0 && throwJson.get()) { 282 throw new JsonException("Some random json exception"); 291 @ParameterizedTest 292 @MethodSource 293 <E extends Exception> void testException(Class<E> exceptionClass, ThrowableInputStream<?> exceptionStream, String exceptionMessage) { 294 E exception = assertThrows(exceptionClass, () -> OsmJsonReader.parseDataSet(exceptionStream, NullProgressMonitor.INSTANCE)); 295 assertEquals(exceptionMessage, ExceptionUtil.explainException(exception)); 296 assertDoesNotThrow(exceptionStream::close); 297 } 298 299 /** 300 * An {@link InputStream} that will throw a specified exception after the first byte is read 301 * @param <E> The exception to be thrown 302 */ 303 private static class ThrowableInputStream<E extends Throwable> extends InputStream { 304 private final Supplier<E> exceptionSupplier; 305 private final ByteArrayInputStream bais; 306 private int read = 0; // Necessary, since otherwise the exception might not be wrapped in a Json exception 307 308 ThrowableInputStream(Supplier<E> exceptionSupplier, byte[] source) { 309 this.exceptionSupplier = exceptionSupplier; 310 this.bais = new ByteArrayInputStream(source); 311 } 312 313 @Override 314 public int read() throws IOException { 315 try { 316 if (read > 0) { 317 E exception = this.exceptionSupplier.get(); 318 if (exception instanceof IOException) { 319 throw (IOException) exception; 320 } else if (exception instanceof RuntimeException) { 321 throw (RuntimeException) exception; 322 } else if (exception != null) { 323 // This shouldn't be possible in actual code, so if something hits this, it is a failure. 324 throw new JosmRuntimeException(exception); 283 325 } 284 return bais.read();285 } finally {286 read++;287 326 } 327 return bais.read(); 328 } finally { 329 read++; 288 330 } 289 }; 290 // Check that a SocketException is properly reported 291 IllegalDataException ide = assertThrows(IllegalDataException.class, 292 () -> OsmJsonReader.parseDataSet(socketExceptionStream, NullProgressMonitor.INSTANCE)); 293 assertEquals("java.net.SocketException: Read timed out", ExceptionUtil.explainException(ide)); 294 assertDoesNotThrow(socketExceptionStream::close); 295 bais.reset(); 296 // Check that a generic exception is properly thrown -- we only want to handle known "good" cases specially 297 throwJson.set(true); 298 assertThrows(JsonException.class, () -> OsmJsonReader.parseDataSet(socketExceptionStream, NullProgressMonitor.INSTANCE)); 299 bais.reset(); 300 // Check that a generic parsing error is properly reported 301 ide = assertThrows(IllegalDataException.class, () -> OsmJsonReader.parseDataSet(bais, NullProgressMonitor.INSTANCE)); 302 assertEquals("jakarta.json.stream.JsonParsingException: Invalid token=COMMA at (line no=1, column no=8, offset=7). " + 303 "Expected tokens are: [COLON]", ExceptionUtil.explainException(ide)); 304 bais.reset(); 305 // Check that an unknown exception is thrown properly 331 } 332 333 @Override 334 public void close() throws IOException { 335 this.bais.close(); 336 super.close(); 337 } 306 338 } 307 339 }
Note:
See TracChangeset
for help on using the changeset viewer.